Encryption TripleDESCryptoServiceProvider-易受拒绝服务攻击?
我们有一个传统ASP.NET站点,它使用以下加密方法: 调用以下方法时,页面加载非常缓慢,最终返回连接重置:Encryption TripleDESCryptoServiceProvider-易受拒绝服务攻击?,encryption,cryptography,denial-of-service,tripledes,Encryption,Cryptography,Denial Of Service,Tripledes,我们有一个传统ASP.NET站点,它使用以下加密方法: 调用以下方法时,页面加载非常缓慢,最终返回连接重置: Decrypt(" ", true); 如果在后续页面请求中多次调用该方法,应用程序池将关闭 这发生在运行.NET framework v3.5的Windows 2008服务器上 我将问题缩小到TransformFinalBlock()调用 注意:在卡西尼号上,我没有连接超时;而是引发以下异常: System.Security.Cryptography.CryptographicEx
Decrypt(" ", true);
如果在后续页面请求中多次调用该方法,应用程序池将关闭
这发生在运行.NET framework v3.5的Windows 2008服务器上
我将问题缩小到TransformFinalBlock()
调用
注意:在卡西尼号上,我没有连接超时;而是引发以下异常:
System.Security.Cryptography.CryptographicException: Bad Data
为其他字符串调用Decrypt()在任何环境中都不会导致问题
为什么会这样?这是TripleDESCryptoServiceProvider中的错误吗
显然,我可以过滤密码字符串以拒绝“”并避免此特定问题。但是,我担心一些我并不怀疑的其他密码字符串值会导致拒绝服务
更新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();
最后一个块是填充的位置。在您的示例中,单个空格是第一个也是最后一个块。DES/Triple DES是一种64位分组密码,密码文本应为8字节(64位)的倍数 我没有环境来测试它,但是你试过使用填充选项吗?用更多的空格填充是不行的,因为填充不匹配 一个常见的填充方案是。对于单个字节(加密到空格字符),纯文本应为十六进制:
0x?? 0x07 0x07 0x07 0x07 0x07 0x07 0x07
但在您的代码示例中,需要base64输入。Wich表示您的输入字符串必须是:
- 12个字符的倍数
- 有效的base64字符串
true
值看起来像MAC,这意味着输入的纯文本后面应该跟一个散列(代码中的MD5)。它可以帮助您检测密码文本的更改。它在加密二进制数据时非常有用。如果可以轻松检测到乱码纯文本,可以将其设置为false。如上所述,问题在于解密逻辑无法正确处理输入密码为零长度数组的情况
已为此创建票证:
请注意,在运行.NET framework 4.0时,它似乎可以正常工作。为什么不逐步执行解密函数,看看当您给它一个带单个空格的字符串时会发生什么情况?@GregS-这正是我所做的。如上所述,我发现TransformFinalBlock()是代码挂起的地方。是的,但是在其他步骤中会发生什么?base64解码器返回什么,依此类推。它返回字节[0]。更新了我的问题的细节。我不禁想知道为什么你的缓冲区被命名为“toEncryptArray”,而你正在创建一个3DES解密程序。您是否有密码文本要用示例密钥(6619 f8cf 6cf9 daf6 67c4 ffe4 34e2 04c2)进行测试您提到密码文本应该是8字节的倍数。但是,如果我将输入更改为8个空格,我仍然存在问题。。。可能一种解决方案是拒绝任何不是有效的Base64字符串的密码字符串,例如:是,但纯文本将为您提供随机密码文本。换句话说,恰好由8个空格组成的密文是非常非常不可能的。如果你得到一个空格作为第一个加密字节(256中有1个),其他字节将是随机的。请参阅我更新的问题。核心问题是,如果输入字节数组为空,解密方法将阻塞。问题是,在解密之前,你永远不知道密文是否有效。无论是.Net还是3DES,加密技术都是这样工作的。您可以对密码文本进行一些快速测试:长度必须是8字节的倍数,0字节总是错误的(原始字节,而不是base64)。如果输入看起来不错,则必须解密并捕获异常。