我们有一个遗留的ASP.NET站点,它使用加密方法:
http://www.codekeep.net/snippets/af1cd375-059a-4175-93d7-25eea2c5c660.aspx
当我们调用以下方法时,页面加载速度非常慢,最终返回Connection Reset:
Decrypt(" ", true);
如果在后续页面请求中多次调用该方法,应用程序池将关闭。
这是在运行.NET framework v3.5的Windows 2008服务器上进行的。
我将问题缩小到TransformFinalBlock()
来电。
注意:在Cassini上,我没有连接超时;而是抛出以下异常:
System.Security.Cryptography.CryptographicException: Bad Data
在其他字符串中调用Decrypt()会导致任何环境都没有问题。
为什么会这样?这是TripleDESCryptoServiceProvider中的错误吗?
显然,我可以过滤cipherString来拒绝“”并避免这个特殊问题。但是,我担心我不怀疑的其他一些cipherString值会导致DoS。
更新2011.06.28
以下是重现问题的最小代码:
// problem occurs when toEncryptArray is an empty array {}
byte[] toEncryptArray = {};
MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
byte[] keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes("dummy_key"));
hashmd5.Clear();
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
tdes.Key = keyArray;
tdes.Mode = CipherMode.ECB;
tdes.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = tdes.CreateDecryptor();
// the following line can crashes the ASP.NET Application Pool (may need to call multiple times).
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
tdes.Clear();
答案 0 :(得分:1)
如上所述,问题在于解密逻辑无法正确处理输入密码为零长度数组的情况。
为此创建了一张票:
注意,运行.NET framework 4.0时似乎工作正常。
答案 1 :(得分:0)
最后一个块是填充的位置。在您的示例中,单个空格是第一个和最后一个块。 DES / Triple DES是一个64位分组密码,密文应该是8字节(64位)的倍数。
我没有环境来测试它,但你尝试使用填充选项吗?填充更多空格不会,因为填充不匹配。
常见的填充方案是PKCS5。对于单个字节(加密到空间字符),您的纯文本应为十六进制:
0x?? 0x07 0x07 0x07 0x07 0x07 0x07 0x07
但是在您的代码示例中,需要base64输入。这意味着您的输入字符串必须是:
任何其他字符串都可以被拒绝。
true
值看起来像MAC,这意味着您的输入纯文本后面应跟一个哈希值(代码中的MD5)。它可以帮助您检测密文的变化。加密二进制数据时很有用。如果您可以轻松检测到乱码的纯文本,则可以将其设置为false。