Encrypt和Decrypt是否使用c#为SQL Server数据库文件工作?

时间:2014-12-19 18:44:43

标签: c# sql-server encryption

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

  

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

请查看我在.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);
                            }
                        }
                    }
                }
            }
        }
    }

1 个答案:

答案 0 :(得分:0)

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

此外,您需要从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);
        }
    }

它生成一个服务器无法读取的虚拟文件。