CRC32+Size vs MD5/SHA1



我们有一个文件存储,该存储根据附加到crc32的大小唯一标识文件。

我想知道这个校验和(crc32 +大小)是否足以识别文件,或者我们应该考虑一些其他哈希技术,如MD5/SHA1?

CRC与其说是一个严肃的哈希函数,不如说是一种错误检测方法。它有助于识别损坏的文件,而不是唯一地标识它们。因此,您应该在MD5和SHA1之间进行选择。

如果你没有很强的安全性需求,你可以选择MD5,它应该更快。(请记住MD5容易受到冲突攻击)。如果你需要更多的安全性,你最好使用SHA1甚至SHA2。

CRC-32不够好;构建冲突是微不足道的,即两个具有相同CRC-32的文件(如果您希望它具有相同长度)。即使没有恶意攻击者,一旦您拥有大约65000个具有相同长度的不同文件,冲突也会随机发生。

哈希函数的设计是为了避免冲突。使用MD5或SHA-1,不会出现随机冲突。如果您的设置与安全相关(例如,在某个地方有人可能会主动尝试创建冲突),那么您需要一个安全的哈希函数。MD5不再安全(使用MD5创建冲突很容易),SHA-1在这方面有些弱(没有计算实际的冲突,但是创建冲突的方法是已知的,虽然昂贵,但比它应该的要便宜得多)。通常的建议是使用SHA-256或SHA-512 (SHA-256足以保证安全性;SHA-512在大型64位系统上可能会快一点,但文件读取带宽将比哈希速度更受限制)。

注意:当使用加密哈希函数时,不需要存储和比较文件长度;哈希值足以消除文件的歧义。

在非安全设置中(即您只担心随机冲突),那么可以使用MD4。它已经彻底"破碎"了。作为加密散列函数,但它仍然是一个非常好的校验和,而且它真的很快(在一些基于arm的平台上,它甚至比CRC-32更快,因为它能更好地抵抗随机碰撞)。基本上,你不应该使用MD5:如果你有安全问题,那么MD5绝对不能使用(它是坏的;使用sha - 256);如果没有有安全问题,那么MD5比MD5快。

将用于CRC32+大小的空间为您提供了足够的空间来容纳更大的CRC,这将是一个更好的选择。如果你不担心恶意碰撞,在这种情况下,托马斯的答案适用。

您没有指定语言,但例如在c++中,您获得了Boost CRC,为您提供了您想要的CRC大小(或者您可以负担得起存储)。

正如其他人所说,CRC不能保证没有冲突。但是,您的问题可以简单地通过为文件提供递增的64位数字来解决。这保证永远不会发生冲突(除非您想在一个目录中保存大量文件,这不是一个好主意)。

老问题,但在谷歌上仍然排名很高,所以它应该得到一个现代的答案:

如果你想要一个适合识别文件的非加密哈希,比CRC32好,但比MD5快,我强烈推荐xxHash系列。

  • 有32位,64位和128位版本,所以关于随机碰撞,比CRC32好得多,和MD5一样强。
  • 比MD5快得多。按10倍(或更多),具体取决于文件大小。见鬼,在一些测试文件中,128位版本甚至比CRC32还要快!
$ time cat       >/dev/null test1G.bin 
real    0m0.099s
user    0m0.000s
sys     0m0.099s
$ time xxh128sum >/dev/null test1G.bin 
                                                                      
real    0m0.169s
user    0m0.113s
sys     0m0.056s
$ time crc32     >/dev/null test1G.bin 
real    0m0.936s
user    0m0.828s
sys     0m0.108s
$ time md5sum    >/dev/null test1G.bin 
real    0m1.554s
user    0m1.502s
sys     0m0.052s
$ time sha1sum   >/dev/null test1G.bin 
real    0m1.717s
user    0m1.616s
sys     0m0.096s

除了命令行工具,它还有多种语言的库,包括C, Java, Python等。

最新更新