.NET加密技术 - 是否有一种方法可以判断解密是否出错?

4

问题的标题已经说明了。

简而言之,我想用用户提供的种子(关键字)加密一些数据。有没有办法知道数据被错误解密,或者换句话说,种子是错误的?

使用 .net 2.0,C#。

谢谢!


2
我想大多数加密引擎如果无法成功解密,都会抛出某种异常。 - Chris Marisic
2
我的经验是,许多加密引擎如果提供有效但不正确的密钥或IV,则不会抛出异常。 - Les
5个回答

5

将哈希值作为加密数据的一部分是非常正常的。比如,你有一些需要加密的数据。你可以创建这些数据的MD5哈希值,并将其添加到数据的末尾。然后,在解密时,你可以获取加密数据末尾的哈希值,并验证哈希值是否发生了变化。


2
但这并不能确定解密是否成功。 - Les
2
当哈希值不匹配时,解密就失败了。在这里,您要做的是检查数据是否被篡改。因为数据已经加密(包括哈希值),所以没有人可以伪造哈希值。因此,当哈希值匹配时,您可以确定数据没有被篡改。一些系统,如EAS,就包含这样的机制。上述描述就是这样的机制,您可以自己实现。 - Pieter van Ginkel
+1 @Pieter,我之前误读了你的答案,我同意你的观点:如果您对原始消息创建哈希摘要,并将其包含在末尾或某个约定的位置,然后加密整个消息和哈希值,那么解密者可以通过重新计算哈希值并检查其是否匹配来几乎确定解密成功。换句话说,只有当原始未加密数据具有一些约定的内置检查值时,才能确定解密是否成功。 - Les
哈希不安全,消息认证码(MAC)也是如此(例如:http://crypto.stackexchange.com/q/16428/13022)。此外,你的建议并不十分清晰:是先加密再哈希,还是先哈希再加密,或者是哈希和加密同时进行(例如:http://crypto.stackexchange.com/q/202/13022)。 - Artjom B.

5
取决于您的算法具体情况。流密码(如RC4)本身将无法检测到任何篡改。块密码(AES)可能会由于块填充算法(PKCS#5)而检测到某些篡改。这种填充检查是导致 ICryptoTransform.TransformFinalBlock` 抛出解密失败异常的原因,但这种检测不是加密安全的(在最坏的情况下,如果填充是一个字节,则有1/256的机会无法检测到篡改)。这不是.Net实现的疏忽,而是使用所有加密算法时的根本问题。
因为解密操作本身基本上无法检测篡改(或使用错误的密钥/IV),所以解决方案是在消息中添加消息的摘要。行业标准是使用 HMAC 摘要,并使密钥派生过程产生足够的密钥材料用于密钥/IV HMAC 密钥(这就是 TLS/SSL 所做的方式,这几乎是“行业标准”,请参见链接的 RFC 的 6.3 Key calculation)。解密步骤解密消息,然后计算消息的 HMAC,将其与原始摘要进行比较。如果它们匹配,则解密成功(使用了正确的密钥/IV)并且消息没有被篡改。

1

0

解决该问题的正式方法是在密钥周围使用key wrap(本身也应加密)。这是因为您只应相信完全私有的密钥,而不是给您的密钥。如果您使用无效的密钥加密数据,则事情会变得糟糕。

在.NET中,没有内置例程(据我所知)来执行密钥包装,但实质上,您可以通过以16个(或任何块大小)'A'字符的字符串作为前缀和后缀来实现相同的效果。当您解密密钥时,请确保其已预先和后缀为'A',如果没有,则标记为错误。

如果您的要求不那么正式,则另一个选项是使用密钥解密一个已知使用正确密钥加密的字符串。如果解密该字符串后得到意外结果,则将其标记为错误。


完整数据的哈希比字符串的哈希提供了稍微更好的保护:在暴力破解或字典攻击期间,需要解密更多的数据才能验证密码的有效性。 - Eugene Mayevski 'Callback
@Eugene。这个回复是给Pieter的吗?我并不是在谈论哈希任何事情。 - PaulG
对整个明文进行哈希的优点是攻击者无法替换密码文本的一部分。我真的不明白你想要实现什么。 - CodesInChaos
@PaulG 首先,对于普通数据来说,差异不是2%,而是20%甚至200%。其次,字典攻击所需时间远远少于一生的时间。如果需要一生的时间,像Elcomsoft这样的公司就会破产,但他们的业绩相当不错。 - Eugene Mayevski 'Callback
@Eugene。抱歉直言,但是3*10^51年的一半仍然是相当长的时间。这段时间不是“针对一个处理器”,而是针对以每秒十亿亿个密钥运行的设备。我也不知道有任何256 字节密钥,也没有人提到会话密钥。您的个人资料显示您受雇于安全专家,因此我很想学习-向我展示任何人提供暴力破解AES的链接。 - PaulG
显示剩余4条评论

0
一个暴力的方法——取决于您对数据做什么......将其推给期望它并查看是否崩溃的任何算法。我有加密的二进制序列化数据,我以这种方式反序列化它。如果数据解密错误并变成噪音,二进制格式化程序会抛出异常。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接