繁体   English   中英

我的SQL Server CLR功能非常慢

[英]My SQL Server CLR function is very slow

我在C#中创建了两个方法:

public static string Encrypt(string clearText, string encryptionKey)
{
        byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);

        using (Aes encryptor = Aes.Create())
        {
            var pdb = new Rfc2898DeriveBytes(encryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
            encryptor.Key = pdb.GetBytes(32);
            encryptor.IV = pdb.GetBytes(16);

            using (var ms = new MemoryStream())
            {
                using (var cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(clearBytes, 0, clearBytes.Length);
                    cs.Close();
                }

                clearText = Convert.ToBase64String(ms.ToArray());
            }
        }

        return clearText;
    }

    public static string Decrypt(string cipherText, string encryptionKey)
    {
        try
        {
            byte[] cipherBytes = Convert.FromBase64String(cipherText);

            using (Aes encryptor = Aes.Create())
            {
                var pdb = new Rfc2898DeriveBytes(encryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
                encryptor.Key = pdb.GetBytes(32);
                encryptor.IV = pdb.GetBytes(16);

                using (var ms = new MemoryStream())
                {
                    using (var cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
                    {
                        cs.Write(cipherBytes, 0, cipherBytes.Length);
                        cs.Close();
                    }

                    cipherText = Encoding.Unicode.GetString(ms.ToArray());
                }
            }
        }
        catch (Exception)
        {
        }

        return cipherText;
    }

通过执行此链接中给出的步骤,我已经在SQL Server中创建了CLR函数,并且尝试将其命名为:

SELECT dbo.Decrypt(MyEncrypted, EncryptionKey)
FROM   MyTable

问题是,这花费了太多时间 像只有1000行一样,花了1.5分钟。 如果我不使用CLR函数调用查询,则花费了不到1秒的时间。

我可以做些什么来改善CLR功能的性能吗?

我已经在VS2010中使用性能分析器分析了您的Decrypt方法,方法是运行100次:

最热的路径是GetBytes

如您所见, Rfc2898DeriveBytes实例的GetBytes方法花费的时间最多。

我不确定您为什么具有这些特定的加密/解密要求,但是影响GetBytes方法花费时间的一种方法是使用将迭代作为第三个参数的构造函数实例化Rfc2898DeriveBytes 默认值为1000,我可以将其设置为低至1。 但是强烈建议您这样做

var pdb = new Rfc2898DeriveBytes(encryptionKey, salt, 10);  

对于EncryptDecrypt ,此迭代确实需要相同,因此如果要更改当前值,则必须对Decrypt \\ Encrypt。

另一种选择可能是按照此答案中的建议缓存IV值。 如果他们还谈论使用相同的Key,我还不够专家,但是如果这是一个选项,那么您也可以将对Key的GetBytes调用也缓存。

所有描述的更改都会影响数据的加密方式和加密强度。 测试解决方案时,请同时考虑这两种影响。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM