加密和解密是否适用于使用 c# 的 SQL Server 数据库文件

本文关键字:SQL Server 数据库 文件 解密 是否 适用于 加密 | 更新日期: 2023-09-27 18:34:41

我正在加密和解密SQL Server数据库.mdf分离后.ldf文件,并且在附加解密文件时收到以下错误消息

文件"C:''DB''Test.mdf"的标头不是有效的数据库文件标头。属性不正确。

请在下面找到我用于.mdf的 C# 代码,这同样适用于我的.ldf文件

private const int KEY_SIZE_BYTES = 32;
private const int IV_SIZE_BYTES = 16; 
private const string  DBFILENAME = @"C:'DB'Test.mdf"; ; 
public void EncryptandDecrypt()
{
        var rand = new Random();
        using (var fs = File.Open(DBFILENAME, FileMode.Create, FileAccess.Write, FileShare.None))
        {
            byte[] buffer = new byte[10000];
            for (int i = 0; i < 100; ++i)
            {
                rand.NextBytes(buffer);
                fs.Write(buffer, 0, buffer.Length);
            }
        }
        string key = GenerateRandomKey();
        Encrypt(DBFILENAME, @"C:'DB'temp'Test.mdf", key);
        Decrypt(@"C:'DB'temp'Test.mdf", DBFILENAME, key);
    }
    public string GenerateRandomKey()
    {
        byte[] key = new byte[KEY_SIZE_BYTES];
        using (var rng = RandomNumberGenerator.Create())
        {
            rng.GetBytes(key);
        }
        return Convert.ToBase64String(key);
    }
    public void Encrypt(string inputFile, string outputFile, string key)
    {
        const int BUFFER_SIZE = 8192;
        byte[] buffer = new byte[BUFFER_SIZE];
        byte[] keyBytes = Convert.FromBase64String(key);
        byte[] ivBytes = new byte[IV_SIZE_BYTES];
        using (var rng = RandomNumberGenerator.Create())
        {
            rng.GetBytes(ivBytes);
        }
        using (var inputStream = File.Open(inputFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        {
            using (var outputStream = File.Open(outputFile, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                outputStream.Write(ivBytes, 0, ivBytes.Length);
                using (var cryptoAlgo = Aes.Create())
                {
                    using (var encryptor = cryptoAlgo.CreateEncryptor(keyBytes, ivBytes))
                    {
                        using (var cryptoStream = new CryptoStream(outputStream, encryptor, CryptoStreamMode.Write))
                        {
                            int count;
                            while ((count = inputStream.Read(buffer, 0, buffer.Length)) > 0)
                            {
                                cryptoStream.Write(buffer, 0, count);
                            }
                        }
                    }
                }
            }
        }
    }
    public void Decrypt(string inputFile, string outputFile, string key)
    {
        const int BUFFER_SIZE = 8192;
        byte[] buffer = new byte[BUFFER_SIZE];
        byte[] keyBytes = Convert.FromBase64String(key);
        byte[] ivBytes = new byte[IV_SIZE_BYTES];
        using (var inputStream = File.Open(inputFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        {
            inputStream.Read(ivBytes, 0, ivBytes.Length);
            using (var outputStream = File.Open(outputFile, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                using (var cryptoAlgo = Aes.Create())
                {
                    using (var decryptor = cryptoAlgo.CreateDecryptor(keyBytes, ivBytes))
                    {
                        using (var cryptoStream = new CryptoStream(inputStream, decryptor, CryptoStreamMode.Read))
                        {
                            int count;
                            while ((count = cryptoStream.Read(buffer, 0, buffer.Length)) > 0)
                            {
                                outputStream.Write(buffer, 0, count);
                            }
                        }
                    }
                }
            }
        }
    }

加密和解密是否适用于使用 c# 的 SQL Server 数据库文件

我已经测试了这段代码,没问题。我认为您可能从临时文件夹或类似标题异常中获取了错误的文件。如果在放回文件时收到访问错误,则必须为解密的文件设置适当的权限。

此外,您还需要从 EncryptDecrypt 方法中删除以下代码并测试真实的数据库文件:

    var rand = new Random();
    using (var fs = File.Open(DBFILENAME, FileMode.Create, FileAccess.Write, FileShare.None))
    {
        byte[] buffer = new byte[10000];
        for (int i = 0; i < 100; ++i)
        {
            rand.NextBytes(buffer);
            fs.Write(buffer, 0, buffer.Length);
        }
    }

它制作了一个服务器无法读取的虚拟文件。