如果有人故意尝试修改两个文件以具有相同的哈希值,有什么方法可以阻止它们?md5 和 sha1 可以防止大多数情况吗?
我正在考虑自己写,我想即使我做得不好,如果用户不知道我的哈希值,他也可能无法欺骗我的哈希值。
防止这种情况的最佳方法是什么?
如果有人故意尝试修改两个文件以具有相同的哈希值,有什么方法可以阻止它们?md5 和 sha1 可以防止大多数情况吗?
我正在考虑自己写,我想即使我做得不好,如果用户不知道我的哈希值,他也可能无法欺骗我的哈希值。
防止这种情况的最佳方法是什么?
如果哈希冲突是一个主要问题,MD5 通常被认为是不安全的。SHA1 同样不再被美国政府认为是可接受的。正在进行一场寻找替代哈希算法的竞赛,但目前建议使用 SHA2 系列 - SHA-256、SHA-384 或 SHA-512。[更新:2012-10-02 NIST选择SHA-3作为算法Keccak。]
您可以尝试创建自己的散列 - 它可能不如 MD5 好,并且“通过默默无闻的安全性”同样不可取。
如果您想要安全性,请使用多种散列算法进行散列。能够使用多种算法同时创建具有哈希冲突的文件是非常不可能的。[并且,根据评论,让我澄清一下:我的意思是同时发布文件的 SHA-256 和 Whirlpool 值——不是结合散列算法来创建单个值,而是使用单独的算法来创建单独的值。通常,损坏的文件将无法匹配任何算法;如果有人设法使用一种算法创建了碰撞值,那么在其他算法之一中也产生第二次碰撞的可能性可以忽略不计。]
公共时间戳使用一组算法。例如,请参阅sqlcmd-86.00.tgz以获取说明。
如果用户不知道您的哈希算法,他也无法在您实际签署的文档上验证您的签名。
最好的选择是使用生成最长散列的公钥单向散列算法。SHA-256 创建一个 256 位哈希,因此伪造者必须尝试 2255个不同的文档(平均而言),然后才能创建与给定文档匹配的文档,这是非常安全的。如果这对您来说仍然不够安全,那么可以使用 SHA-512。
另外,我认为值得一提的是,保护自己免受伪造的数字签名文档的一种低技术含量的好方法是简单地保留您签名的任何内容的副本。这样,如果发生争议,您可以证明您签署的原始文件已被更改。
这里有一个难度等级(对于攻击者)。找到两个具有相同散列的文件比生成一个匹配给定散列的文件更容易,如果您不必遵守形式/内容/长度限制,则以后更容易做到。
因此,如果可以使用定义良好的文档结构和长度,那么无论您使用什么底层哈希,都可以让攻击者的生活更加艰难。
您为什么要尝试创建自己的哈希算法?SHA1HMAC 有什么问题?
是的,哈希有重复。
任何比明文短的散列必然是更少的信息。这意味着会有一些重复。哈希的关键是重复很难逆向工程。
考虑 CRC32 - 通常用作散列。这是一个 32 位的数量。因为宇宙中有超过 2^32 条消息,那么就会有 CRC32 的重复。同样的想法也适用于其他哈希。
这称为“哈希冲突”,避免它的最佳方法是使用强哈希函数。MD5 相对容易人为地构建冲突文件,如此处所示。同样,已知有一种相对有效的方法来计算碰撞 SH1 文件,尽管在这种情况下“相对有效”仍需要数百小时的计算时间。
一般来说,MD5 和 SHA1 的破解成本仍然很高,但并非不可能。如果您真的担心它,请使用更强的哈希函数,例如SHA256。
除非您是一位非常专业的密码学家,否则编写自己的代码实际上并不是一个好主意。大多数简单的想法都已经尝试过了,并且有针对它们的众所周知的攻击。
如果您真的想了解更多信息,请查看 Schneier 的Applied Cryptography。
我不认为提出自己的哈希算法是一个好的选择。
另一个不错的选择是使用Salted MD5。例如,在传递给 MD5 函数之前,您的 MD5 哈希函数的输入会附加字符串“acidzom!@#”。
在Slashdot也有很好的阅读。