什么时候CRC比MD5 / SHA1更适合使用?

何时使用CRC进行错误检测与比较现代的散列函数(如MD5或SHA1)是否合适? 前者更容易在embedded式硬件上实现吗?

CRC可以很好地检测可能发生的数据中的随机错误,例如,来自networking干扰,线路噪声,失真等。

CRC在计算上比MD5或SHA1复杂得多。 使用像MD5这样的哈希函数对于随机错误检测可能是过度的。 然而,使用CRC进行任何types的安全检查比起更复杂的散列函数(如MD5)要安全得多。

是的,CRC在embedded式硬件上实现起来要容易得多,您甚至可以在IC上获得不同的封装解决scheme。

CRC旨在防止数据中的无意变化。 也就是说,检测意外错误是很好的,但是对于确保数据不被恶意处理是没有用的。

也看到这个 。

我发现一个研究表明不恰当的 CRC散列是如何散列表 。 它也解释了algorithm的实际特征。 该研究还包括其他哈希algorithm的评估,是一个很好的参考。

关于CRC的CRC相关结论:

CRC32从来没有用于散列表的使用。 实际上没有什么理由使用它,我build议你避免这样做。 如果您决定使用CRC32,那么使用与input关键八位字节相反端的哈希位是至关重要的。哪一端取决于具体的CRC32实现。 不要将CRC32视为“黑盒子”散列函数,不要将其用作通用散列函数。 一定要testing它的每个应用程序的适用性。

UPDATE

看来这个网站已经倒闭了。 互联网档案有一个副本 。

我在1.000.000循环中运行了这个PHP代码的每一行。 结果在注释(#)中。

hash('crc32', 'The quick brown fox jumped over the lazy dog.');# 750ms 8 chars hash('crc32b','The quick brown fox jumped over the lazy dog.');# 700ms 8 chars hash('md5', 'The quick brown fox jumped over the lazy dog.');# 770ms 32 chars hash('sha1', 'The quick brown fox jumped over the lazy dog.');# 880ms 40 chars hash('sha256','The quick brown fox jumped over the lazy dog.');# 1490ms 64 chars hash('sha384','The quick brown fox jumped over the lazy dog.');# 1830ms 96 chars hash('sha512','The quick brown fox jumped over the lazy dog.');# 1870ms 128 chars 

我的结论是:

有关CRC的实施信息,速度和可靠性,请参阅CRC错误检测algorithm的无痛指南 。 它具有一切CRC。

除非有人会尝试恶意修改你的数据,并且隐藏更改CRC就足够了。 只要使用“好”(标准)多项式即可。

你不会说你试图保护什么。

CRC通常用于embedded式系统,以防止意外数据损坏,而不是防止恶意系统修改。 CRC可用的地方的例子是在系统初始化期间validationEPROM图像以防止固件损坏。 系统自举程序将计算应用程序代码的CRC并在允许代码运行之前与存储的值进行比较。 这可以防止意外程序损坏或下载失败的可能性。

CRC也可以以类似的方式用于保护存储在FLASH或EEPROM中的configuration数据。 如果CRC不正确,则可以将数据标记为无效,并使用默认或备份数据集。 由于设备故障或用户在更新configuration数据存储期间断电,CRC可能无效。

有评论认为,散列比具有多位错误的CRC提供更高的检测损坏概率。 这是真的,关于是否使用16位或32位CRC的决定将取决于所使用的数据块是否受到损坏的安全性,以及是否可以certificate1 ^ 2 ^ 16或2 ^ 32的机会数据块被错误地声明为有效。

许多设备都有标准algorithm的内置CRC生成器。 得克萨斯州的MSP430F5X系列具有CRC-CCITT标准的硬件实现。

CRC32更快,散列长度只有32位。

当你只需要一个快速和轻量的校验和时使用它。 CRC用于以太网。

如果你需要更多的可靠性,最好使用现代哈希函数。

如果计算资源非常紧密(即某些embedded环境),则只能使用CRC,或者需要存储/传输多个输出值,空间/带宽也很紧凑(因为CRC通常是32位,其中MD5输出是128位,SHA1 160位以及其他SHA变体,最高可达512位)。

不要使用CRC进行安全检查,因为CRC很容易“伪造”。

即使对于意外错误检测(而不是恶意变化检测),散列也比简单的CRC要好。 部分原因是由于计算CRC的简单方式(部分原因是由于CRC值通常比常见的哈希输出短,因此可能值的范围小得多),所以更有可能的是,在存在两个或更多个错误的情况下,一个错误会掩盖另一个错误,所以尽pipe出现了两个错误,但最终会得到相同的CRC。

简而言之:除非你有理由使用体面散列algorithm,否则应避免使用简单的CRC。

CRC32速度更快,有时还有硬件支持(即在Nehalem处理器上)。 真的,唯一一次你使用它是如果你与硬件接口,或者如果你是非常严格的性能

我最近遇到了一个很聪明的CRC的使用。 jdupe文件复制识别和删除工具的作者(stream行的exif工具jhead的同一作者)在第一次通过文件时使用它。 在每个文件的第一个32K上计算一个CRC来标记看起来相同的文件,文件也必须具有相同的大小。 这些文件被添加到一个完整的二进制比较文件列表。 它加速检查大型媒体文件。

让我们从基础开始。

在密码学中,哈希algorithm通过摘要操作将许多比特转换为更less的比特。 哈希用于确认消息和文件的完整性。

所有散列algorithm都会产生冲突。 碰撞是几个多位组合产生相同的较less位输出。 散列algorithm的密码强度是由个体无法确定给定input的输出是什么所决定的,因为如果他们能够构build一个散列文件来匹配合法文件,并且损害假定的完整性的系统。 CRC32和MD5之间的区别在于MD5产生了一个更难以预测的更大的散列。

当你想要实现消息的完整性 – 意味着消息在传输过程中没有被篡改 – 无法预测冲突是一个重要的属性。 32位散列可以使用40亿个不同的独特散列来描述40亿个不同的消息或文件。 如果你有40亿和1个文件,你保证有1个碰撞。 1 TB Bitspace有数十亿个碰撞的可能性。 如果我是一个攻击者,我可以预测这个32位散列将会是什么,我可以构造一个与目标文件相冲突的受感染文件; 有相同的散列。

另外,如果我在做10mbps传输,那么数据包被破坏的可能性正好绕过crc32,并继续沿着目的地和执行是非常低的。 比方说10mbps我得到10个错误\第二 。 如果我把这个速度提高到1Gbps,那么现在我每秒钟会收到1000个错误 。 如果我每秒猛击1次,那么每秒错误率为10 亿次 。 假设我们有一个1 / 1,000,000个传输错误的冲突率,意思是百万传输错误中的1个导致错误的数据通过未被检测到。 在10mbps时,我会得到错误数据每10万秒发送一次或大约每天一次。 以1gbps的速度每5分钟发生一次。 每秒1次,我们每秒说几次。

如果你打开Wireshark,你会看到你的典型的以太网头有一个CRC32,你的IP头有一个CRC32,你的TCP头有一个CRC32,这是除了高层​​协议可以做什么, 除了上述之外,IPSEC可能使用MD5或SHA进行完整性检查。 在典型的networking通信中有几层错误检测,并且它们仍然以10mbps以下的速度一次又一次地出现。

循环冗余校验(CRC)有几个常见的版本和几个不常见的,但通常被devise为只是告诉当一个消息或文件已经损坏运输(多位翻转)。 CRC32本身并不是一个很好的错误检查协议,由于当前的标准,在大型的标量企业环境中,由于冲突率; 普通用户的硬盘可以有10万以上的文件,公司的文件共享可以有数千万。 散列空间与文件数量的比率太低。 CRC32计算便宜,而MD5不是。

MD5被devise为停止有意使用collissions使恶意文件看起来恶性。 这被认为是不安全的,因为哈希空间已经足够的映射,使一些攻击的发生,一些collissions是可以食用的。 SHA1和SHA2是这个街区的新孩子。

对于文件validation,Md5开始被许多供应商使用,因为你可以用它来快速地完成数兆字节的文件或者多字节文件,并且堆叠在一般操作系统的使用和CRC32的支持之上。 如果在接下来的十年内文件系统开始使用MD5进行错误检查,请不要惊讶。

这一切都取决于你的要求和期望。

以下是这些散列函数algorithm之间的简要差别:

CRC (CRC-8/16/32/64)

  • 不是密码哈希algorithm(它使用基于循环冗余校验的线性函数)
  • 可以产生9,17,33或65位
  • 不打算用于密码的目的,因为没有encryption保证,
  • 不适合用于数字签名,因为它很容易在2006年逆转,
  • 不应该用于encryption目的,
  • 不同的string可以产生碰撞,
  • 发明于1961年,用于以太网等多种标准,

MD5

  • 是一个密码散列algorithm,
  • 产生一个128位(16字节)散列值(32位hex数)
  • 这是一个encryption散列,但是如果您担心安全性,则被视为弃用,
  • 有已知的string具有相同的MD5散列值
  • 可以用于encryption目的,

SHA-1

  • 是一个密码散列algorithm,
  • 产生一个160位(20字节)散列值,称为消息摘要
  • 这是一个密码散列,自2005年以来,它不再被认为是安全的,
  • 可以用于encryption目的,
  • 已发现一个sha1碰撞的例子
  • 首先在1993年(作为SHA-0)出版,然后在1995年作为SHA-1出版,
  • 系列:SHA-0,SHA-1,SHA-2,SHA-3,

    总之,对于资金充足的对手来说,使用SHA-1已经不再被认为是安全的,因为2005年,密码分析师发现了对SHA-1的攻击,这表明它可能对于正在使用的schneier来说不够安全。 美国NISTbuild议,联邦机构应该停止使用SHA1-1进行需要抗冲击的应用,并且必须在2010年NIST之后使用SHA-2。

因此,如果您正在寻找简单而快速的解决scheme来检查文件的完整性(反对损坏),或者在性能方面进行一些简单的高速caching目的,则可以考虑使用CRC-32进行散列,您可能会考虑使用MD5,但是如果你正在开发专业应用程序(这应该是安全和一致的),以避免任何碰撞概率 – 使用SHA-2及以上(如SHA-3)。

性能

PHP中的一些简单的基准testing:

 # Testing static text. $ time php -r 'for ($i=0;$i<1000000;$i++) crc32("foo");' real 0m0.845s user 0m0.830s sys 0m0.008s $ time php -r 'for ($i=0;$i<1000000;$i++) md5("foo");' real 0m1.103s user 0m1.089s sys 0m0.009s $ time php -r 'for ($i=0;$i<1000000;$i++) sha1("foo");' real 0m1.132s user 0m1.116s sys 0m0.010s # Testing random number. $ time php -r 'for ($i=0;$i<1000000;$i++) crc32(rand(0,$i));' real 0m1.754s user 0m1.735s sys 0m0.012s\ $ time php -r 'for ($i=0;$i<1000000;$i++) md5(rand(0,$i));' real 0m2.065s user 0m2.042s sys 0m0.015s $ time php -r 'for ($i=0;$i<1000000;$i++) sha1(rand(0,$i));' real 0m2.050s user 0m2.021s sys 0m0.015s 

有关:

  • PHP上的md5(),crc32()和sha1()encryption有什么区别?

CRC码更简单快捷。

你需要什么?