【问题标题】:When is CRC more appropriate to use than MD5/SHA1?CRC 何时比 MD5/SHA1 更适合使用?
【发布时间】:2023-03-27 01:37:01
【问题描述】:

相比 MD5 或 SHA1 等更现代的散列函数,何时更适合使用 CRC 进行错误检测?前者更容易在嵌入式硬件上实现吗?

【问题讨论】:

    标签: hash embedded crc


    【解决方案1】:

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

    CRC 在计算上比 MD5 或 SHA1 简单得多。使用像 MD5 这样的散列函数对于随机错误检测来说可能是多余的。但是,使用 CRC 进行任何类型的安全检查都远不如 MD5 等更复杂的散列函数安全。

    是的,CRC 更容易在嵌入式硬件上实现,您甚至可以在 IC 上获得不同的封装解决方案。

    【讨论】:

    • @gili:您总是可以将双字异或在一起得到一个结果双字。
    • @Dustin:您的回答完全正确,但也许考虑将“CRC 在计算上更高效”更改为“CRC 在计算上更容易”? MD5/SHA-1 算法很复杂,但并非真正“低效”的 IMO。
    • @coxymla 你是对的,我应该使用的词是“复杂”而不是“低效”。谢谢!
    • 要将任何长散列减少到 32 位,只需取前 32 位。
    • 如果安全是您的目标,那么您永远不应该使用MD5,也应该避免使用SHA-1,建议使用SHA-2 的一些变体。
    【解决方案2】:

    CRC 旨在防止数据发生意外更改。 也就是说,它有助于检测意外错误,但无法确保数据未被恶意处理。

    另见this

    【讨论】:

    • 此答案中链接中最重要的部分:“(...)即使是 2048 位 CRC 在加密上也比 128 位 MD5 安全性要低得多”
    • 虽然答案仍然正确,但如今 MD5 和 SHA1 处于同一安全级别。换句话说,只适用于检测意外错误。
    【解决方案3】:

    我发现了一项显示how inappropriate CRC hashes are for hash tables 的研究。它还解释了算法的实际特征。 The study 还包括其他哈希算法的评估,是一个很好的参考。

    更新

    该网站似乎已关闭。 internet archive has a copy 不过。

    更新 2

    哦,亲爱的。 It turns out the study may have been faulty around the conclusions on CRC for use as a hash。感谢@minexew 提供链接。

    【讨论】:

    • 链接已损坏。也许你可以自己写解释?如果不是,答案是没有用的。
    • 好的,我会在我的回答中包含结论。
    • 奇怪,根据基准here,CRC 实际上在速度和碰撞次数方面做得很好。
    • 确实很有趣。我不得不再次查看我链接到的研究,但如果我不得不猜测这一定是因为不同的测试实现。如果我必须做出决定,我会从研究中寻求建议,它似乎更科学合理。
    • 在我对数百万个 URL 进行哈希处理的经验中,CRC64 碰撞了 8 次,MD5 碰撞了 5 次。显然 MD5 更好,但 CRC64 是一个很棒、更快、更简单的哈希。
    【解决方案4】:

    我在 1.000.000 循环中运行了这段 PHP 代码的每一行。结果以 cmets (#) 为单位。

    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
    

    我的结论:

    • 当您需要http://en.wikipedia.org/wiki/Cyclic_redundancy_check 和时使用“crc32b” 你不关心安全。
    • 当您需要添加安全层时,请使用“sha256”(或更高版本)。

    • 不要使用“md5”或“sha1”,因为它们有:

      1. 当您关心安全时的一些安全问题
      2. 哈希字符串更长,当您只需要 CRC 时比“crc32b”慢

    【讨论】:

    • 并非如此。 echo hash('crc32', 'The quick brown fox jumped over the lazy dog.'); echoes "413a86af",什么是 8 个字符长的字符串。顺便说一句,它是以 HEX 格式存储的 32 位数字。例如,“sha256”有 256 位哈希,同样存储为 HEX,得到 64 个字符的长字符串。
    • 这些结果非常具有欺骗性。当将这些散列算法应用于大型数据集(War and Peace 而不是 "The quick brown fox jumped over the lazy dog.")时,您会看到 CRC 比 MD5 快多少。
    • 有一种中间情况(在库中重复检查),其中 MD5/Sha1 是正确的解决方案:他们不需要处理对手精心制作几乎不可能的哈希冲突的情况,但是他们确实需要处理意外碰撞。因此:检测位错误和损坏:CRC32 检测库中的冲突:MD5/SHA1 对抗性应用程序:Sha256 及更高版本。当然,如果您有一个包含数十亿条目的库,那么您可能也需要增加哈希位。
    • PHP?在 ARM 平台上,嵌入式代码,16MHz 一个 46 字节的 CRC32,可能是 12 微秒。那有硬件辅助。即使是硬件辅助的 AES 也会慢几百倍。无辅助查找表 CRC 仍应在 50 微秒左右到达。
    【解决方案5】:

    有关实施、速度和可靠性的 CRC 信息,请参阅A painless guide to CRC error detection algorithms。它包含 CRC 上的所有内容。

    除非有人试图恶意修改您的数据并隐藏更改 CRC 就足够了。只需使用“良好”(标准)多项式即可。

    【讨论】:

      【解决方案6】:

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

      以下是这些hash function 算法之间的简要区别:

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

      • 不是加密哈希算法(它使用基于循环冗余检查的线性函数)
      • 可以产生 9、17、33 或 65 位
      • 不用于加密目的,因为不提供任何加密保证,
      • 不适合用于数字签名,因为它很容易可逆2006,
      • 不应用于加密目的,
      • 不同的字符串会产生冲突,
      • 发明于 1961 年,用于以太网和许多其他标准,

      MD5

      SHA-1

      • 是一种加密哈希算法,

      • 产生一个称为消息摘要的 160 位(20 字节)散列值

      • 它是一种加密散列,自 2005 年以来它不再被认为是安全的,

      • 可用于加密目的,

      • an example of a sha1 collision has been found

      • 于 1993 年首次发布(作为 SHA-0),然后在 1995 年作为 SHA-1 发布,

      • 系列:SHA-0、SHA-1、SHA-2、SHA-3,

        总之,使用 SHA-1 不再被认为对资金充足的对手是安全的,因为在 2005 年,密码分析员发现了对 SHA-1 的攻击,这表明它可能不够安全,无法继续使用schneier。美国 NIST 建议联邦机构应停止将 SHA1-1 用于需要抗碰撞的应用,并且必须在 2010 年后使用 SHA-2NIST

      因此,如果您正在寻找简单快捷的解决方案来检查文件的完整性(防止损坏),或者出于性能方面的一些简单缓存目的,您可以考虑使用 CRC-32,因为您可以考虑使用 MD5,但是如果您正在开发专业应用程序(应该是安全且一致的),为了避免任何冲突概率 - 使用 SHA-2 及更高版本(例如 SHA-3)。

      性能

      一些简单的 PHP 基准测试:

      # 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
      

      相关:

      【讨论】:

        【解决方案7】:

        你没有说你想要保护的是什么。

        CRC 通常用于嵌入式系统中,以防止意外数据损坏,而不是防止恶意系统修改。 CRC 可能有用的地方的示例是在系统初始化期间验证 EPROM 映像以防止固件损坏。系统引导加载程序将计算应用程序代码的 CRC,并在允许代码运行之前与存储的值进行比较。这可以防止意外程序损坏或下载失败的可能性。

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

        有一些 cmets 表明,与具有多个位错误的 CRC 相比,散列提供了更大的检测损坏的可能性。确实如此,是否使用 16 位或 32 位 CRC 的决定将取决于正在使用的损坏数据块的安全后果,以及您是否可以证明 2^16 或 2^32 中的 1 概率是合理的数据块被错误地声明为有效。

        许多设备都内置了用于标准算法的 CRC 生成器。 Texas 的 MSP430F5X 系列具有 CRC-CCITT 标准的硬件实现。

        【讨论】:

          【解决方案8】:

          CRC32 更快,哈希只有 32 位长。

          当您只想要一个快速而轻松的校验和时使用它。 CRC 用于以太网。

          如果您需要更高的可靠性,最好使用现代散列函数。

          【讨论】:

            【解决方案9】:

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

            【讨论】:

            • 该方法的一个问题是,当在其中包含嵌入的 CRC32 的文件上运行时,生成的 CRC 可能与文件中的数据无关(因为如果数据更改,CRC32 将更改以抵消差异)。在计算 CRC32 之前以某种简单的方式修改数据可以避免这个问题。
            • @supercat - 我真的不相信这实际上是一个问题。如果一个文件包含一个 crc32 头,它是文件其余部分的 crc32,那么当文件更新时,crc32 头中的每个位将有大约 50% 的机会不同。标头中的更改应遵循相当随机的分布。我看不出这将如何导致 CRC32(header + data) 始终相同,或者以任何方式不依赖于文件的数据部分。
            • @tereratorn:我看到很多文件末尾都有 CRC32,计算方式是整个文件的 CRC32,使用某些特定的种子常数计算,将始终为其他一些常数值。这在二进制代码图像之类的东西中很常见。如果 Acme 1000 DVD 播放器使用固定大小的代码映像进行固件升级,并且期望每个代码映像都具有特定的 CRC32,那么计算各种文件的 CRC32 的例程将无法区分 Acme 1000 的不同代码映像。
            • 这种情况下CRC的重点是快速识别文件不同。如果 CRC 返回相同,您现在必须进行昂贵的二进制比较,因此嵌入式 CRC 不会破坏算法。可能会发生某些文件最终被二进制比较的情况,因为 CRC 第一次通过表明它们可能相同,但不太可能是很多文件,您可以通过使用自定义多项式来避免这种情况。
            【解决方案10】:

            仅当计算资源非常紧张(即某些嵌入环境)或您需要存储/传输许多输出值且空间/带宽紧张时才使用 CRC(因为 CRC 通常是 32 位,而 MD5 输出是 128 位、SHA1 160 位和其他 SHA 变体高达 512 位)。

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

            即使对于意外错误检测(而不是恶意更改检测),哈希也比简单的 CRC 更好。部分是因为计算 CRC 的方法很简单(部分是因为 CRC 值通常比常见的哈希输出短,因此可能值的范围要小得多),在有两个或多个错误的情况下,更有可能发生这种情况, 一个错误会掩盖另一个错误,因此尽管有两个错误,但您最终会得到相同的 CRC。

            简而言之:除非您有理由使用像样的哈希算法,否则请避免使用简单的 CRC。

            【讨论】:

            • 如果您使用正确的多项式,CRC 将捕获所有意外的数据更改。如果恰好更改了正确的多个位,则会错过 1/2^32 的更改。
            • 并且使用适当的多项式,它还将捕获某些常见类的所有错误,例如突发错误。
            • 我同意你的回答,除了问题是关于嵌入式系统的。加密算法的性能在较小的嵌入式系统上可能会出现问题。
            • 绝对不同意这一点。 CRC 错误多项式经过精心挑选,以便在某些情况下可以检测到 1、2、3、5 和突发错误,最高可达 11 位。加密哈希是纯粹的统计数据,因此您必须使用较大的摘要值。 8-32 位对于加密哈希摘要是不现实的,并且在 cpu cyles 和门中毫无意义地昂贵。如果您在嵌入式系统上工作,绝对不是一个可以接受的答案。唯一不使用 CRC 的情况是您必须处理智能对手场景。
            【解决方案11】:

            让我们从基础开始。

            在密码学中,散列算法通过摘要操作将许多位转换为更少的位。哈希用于确认消息和文件的完整性。

            所有散列算法都会产生冲突。冲突是指几个多位组合产生相同的较少位输出。散列算法的加密强度是由个人无法确定给定输入的输出将是什么来定义的,因为如果他们可以构造一个具有与合法文件匹配的散列的文件并损害假定的完整性的系统。 CRC32 和 MD5 的区别在于 MD5 生成的散列更大,更难预测。

            当您想要实现消息完整性时 - 意味着消息在传输过程中没有被篡改 - 无法预测冲突是一个重要属性。 32 位散列 可以描述 40 亿个不同的消息 或使用 40 亿个不同的唯一散列的文件。如果你有 40 亿个和 1 个文件,你肯定会发生 1 次冲突。 1 TB 位空间有数十亿次碰撞的可能性。如果我是攻击者并且我可以预测 32 位散列将是什么,我可以构造一个与目标文件冲突的受感染文件;具有相同的哈希值。

            另外,如果我进行 10mbps 的传输,那么数据包被破坏以绕过 crc32 并继续沿着目的地执行的可能性非常低。假设在 10mbps 时我得到 10 个错误\秒。如果我将其提高到 1gbps,现在我会得到 每秒 1,000 个错误。如果我以每秒 1 exabit 的速度运行,那么我的错误率为 每秒 1,000,000,000 个错误。假设我们有 1\1,000,000 个传输错误的冲突率,这意味着百万分之一的传输错误会导致损坏的数据未被检测到。在 10mbps 时,我会每 100,000 秒或大约每天一次发送错误数据。在 1gbps 时,它每 5 分钟发生一次。以每秒 1 exabit 的速度,我们每秒会说几次。

            如果您打开 Wireshark,您会看到典型的以太网标头具有 CRC32,您的 IP 标头具有 CRC32,您的 TCP 标头具有 CRC32,这是上层协议可能做的补充;例如除了上述之外,IPSEC 还可能使用 MD5 或 SHA 进行完整性检查。在典型的网络通信中存在多层错误检查,它们仍然会时不时地以低于 10mbps 的速度进行检查。

            循环冗余校验 (CRC) 有几个常见的版本和几个不常见的版本,但通常仅用于判断消息或文件在传输过程中何时损坏(多位翻转)。由于冲突率,CRC32 本身在大型标量企业环境中按照当今的标准并不是一个非常好的错误检查协议;普通用户的硬盘驱动器可以有超过 100k 的文件,而公司的文件共享可以有数千万。哈希空间与文件数量的比率太低了。 CRC32 在计算上实现起来很便宜,而 MD5 则不然。

            MD5 旨在阻止故意使用冲突来使恶意文件看起来是良性的。它被认为是不安全的,因为哈希空间已被充分映射以使某些攻击能够发生,并且某些冲突是可预测的。 SHA1 和 SHA2 是新来的。

            对于文件验证,Md5 开始被许多供应商使用,因为您可以使用它快速处理数千兆字节或数兆字节的文件,并将其叠加在通用操作系统对 CRC32 的使用和支持之上。如果在未来十年内文件系统开始使用 MD5 进行错误检查,请不要感到惊讶。

            【讨论】:

              【解决方案12】:

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

              【讨论】:

                【解决方案13】:

                CRC 代码更简单、更快。

                你需要什么?

                【讨论】:

                  猜你喜欢
                  • 2011-07-03
                  • 2011-12-27
                  • 2013-02-07
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-04-13
                  • 2016-06-14
                  • 2013-06-17
                  • 1970-01-01
                  相关资源
                  最近更新 更多