CRC何时比MD5/SHA1更适合使用?

Gil*_*ili 121 embedded hash crc

何时使用CRC进行错误检测而不是更现代的散列函数(如MD5或SHA1)?前者在嵌入式硬件上更容易实现吗?

def*_*nes 105

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

CRC在计算上远不如MD5或SHA1复杂.使用像MD5这样的散列函数可能会对随机错误检测造成过大的影响.但是,对于任何类型的安全检查使用CRC将比诸如MD5之类的更复杂的散列函数安全得多.

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

  • 要将任何长哈希减少到32位,只需取前32位. (27认同)
  • 如果安全是您的目标,那么您永远不应该使用“MD5”,也应该避免使用“SHA-1”,建议使用“SHA-2”的某些变体。 (3认同)
  • @Dustin:你的答案是完全正确的,但也许考虑改变"CRC在计算上更有效率"到"CRC在计算上更容易"?MD5/SHA-1算法很复杂,但并不是真正"低效"的IMO. (2认同)

Lir*_*evi 30

CRC旨在防止数据中的无意更改.也就是说,它有助于检测无意的错误,但作为确保数据未被恶意处理的方法将毫无用处.

也看到这个.

  • 尽管答案仍然是正确的,但如今MD5和SHA1处于相同的安全级别。换句话说,仅对于检测意外错误有用。 (2认同)

And*_*uus 19

我发现了一项研究,显示了哈希表的CRC哈希值是多么不合适.它还解释了算法的实际特征.该研究还包括对其他哈希算法的评估,是一个很好的参考.

关于哈希的CRC的相关结论:

CRC32从未打算用于哈希表.没有充分的理由将其用于此目的,我建议您不要这样做.如果您决定使用CRC32,那么使用与密钥八位字节输入相反的末端的散列位是至关重要的.这取决于具体的CRC32实现.不要将CRC32视为"黑盒子"哈希函数,也不要将其用作通用哈希.务必测试每个应用程序的适用性.

UPDATE

看来该网站已关闭.在互联网档案馆有一个副本,但.


Mar*_*tin 19

我在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
Run Code Online (Sandbox Code Playgroud)

我的结论:

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

  • 不要使用"md5"或"sha1",因为他们有:

    1. 当您关心安全性时会遇到一些安全问题
    2. 当你需要的只是CRC时,更长的哈希字符串并且比"crc32b"慢

  • 这些结果非常具有欺骗性.当这些哈希算法应用于大型数据集([战争和平](http://en.wikipedia.org/wiki/War_and_Peace)而不是"快速的棕色狐狸跳过懒狗."`)会看到CRC比MD5快多少. (42认同)
  • 有一个中间情况(库中的重复检查),其中 MD5/Sha1 是正确的解决方案:他们不需要处理有对手精心设计几乎不可能的哈希冲突的情况,但他们确实需要处理意外冲突。所以:检测位错误和损坏:CRC32 检测库中的冲突:MD5/SHA1 对抗性应用程序:Sha256 及更高版本。当然,如果您有一个包含数十亿个条目的库,那么您可能也需要增加哈希位。 (2认同)

Ger*_*ard 11

有关CRC实现,速度和可靠性的信息,请参阅CRC错误检测算法的无痛指南.它拥有CRC上的所有功能.

除非有人试图恶意修改您的数据并隐藏更改CRC就足够了.只需使用"好"(标准)polinomial.


ben*_*nrg 9

在检测随机错误方面,短 CRC比相同长度的伪随机哈希要好得多。

\n

多年来,这个问题已经积累了大量答案,但大多数答案都是不必要的,但还没有一个答案指出这个关键事实。即使您可以承受计算成本,也不应该使用短随机哈希(例如截断的 MD5 或 SHA-1)来捕获偶尔翻转的位,因为误报率会很高。

\n

这是一个有效的例子。假设您的消息是 12 个八位位组(96 位)的有效负载加上 1 个用于错误检测的八位位组。还假设每个位在传输过程中有万分之一的独立机会被损坏(翻转)。请注意,这意味着大约 1% 的数据包将至少有 1 个翻转位,大约 0.01% 的数据包将至少有 2 个翻转位,依此类推。

\n

如果错误检测位是伪随机散列(例如截断为 8 位的 MD5 或 SHA-1),则始终会检测到仅限于校验位的损坏,而不限于这些位的损坏将在 255/256 左右被检测到的时间。总而言之,大约 (12/13)\xc3\x97(1/256) \xe2\x89\x88 0.36% 的损坏数据包将逃避检测。

\n

如果错误检测位是一个简单的校验和(其他字节的总和模 256),则将检测到所有单位翻转错误(占总数的 99%),并且在剩余的 1% 中,优于 7/将检测到 8 个。不到 0.13% 的损坏数据包将被丢失。因此,即使是简单的校验和也优于随机哈希。

\n

如果错误检测位是具有适当选择的多项式的 CRC-8(例如 CRC-8-CCITT),则将检测到 1、2 或 3 个翻转位的所有错误,以及大约 127/128 的其他错误将被检测到。不到 0.00000002% 的损坏数据包将被丢失。

\n

使用 CRC 不仅是因为它们计算速度快(尽管它们是\xe2\x80\x94,尤其是在硬件中),而且还因为它们非常擅长检测某些类型的错误。即使您使用的硬件计算截断 MD5 的速度比计算 CRC-8 的速度快,您可能仍然应该使用 CRC。

\n
\n

如果你有更多的空间用于校验和 \xe2\x80\x93 128 位,比如 \xe2\x80\x93 那么情况就不同了。CRC-128 仍然比 128 位随机哈希具有理论上的优势,但随机哈希的漏报率(大约 2 \xe2\x88\x92128)已经很低,甚至可以视为零; 降低它并没有真正的好处。如果您有能力在这种情况下使用 MD5 哈希,那么您也可以使用它。

\n

如果您试图检测恶意引入的错误,那么事情就会变得更加复杂。在这种情况下,有必要使用某种加密哈希(不是 CRC),但这还远远不够。如果您确实需要设计一个可以安全抵御恶意干扰的协议,那么您应该在 Cryptography Stack Exchange 上询问。不要认为使用 SHA-3 或 BLAKE2 等现代哈希足以保证您的安全。可能不是。

\n


uɐɪ*_*uɐɪ 8

你没有说你试图保护的是什么.

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

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

有评论认为,与具有多个位错误的CRC相比,散列提供更大的检测损坏的可能性.这是真的,关于是否使用16位或32位CRC的决定将取决于所使用的已损坏数据块的安全性后果以及您是否可以证明1或2 ^ 16或2 ^ 32的机会是合理的.数据块被错误地声明为有效.

许多设备都有内置的CRC生成器,用于标准算法.德克萨斯州的MSP430F5X系列具有CRC-CCITT标准的硬件实现.


ken*_*orb 7

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

以下是这些哈希函数算法之间的快速简短差异:

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

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

MD5

SHA-1

  • 是一种加密哈希算法,
  • 生成一个160位(20字节)的哈希值,称为消息摘要
  • 它是一个加密哈希,自2005年以来它不再被认为是安全的,
  • 可用于加密目的,
  • 已找到sha1碰撞的示例
  • 首次发表于1993年(作为SHA-0),然后1995年作为SHA-1发表,
  • 系列:SHA-0,SHA-1,SHA-2,SHA-3,

    总之,使用SHA-1不再被认为对资金充足的对手是安全的,因为在2005年,密码分析师发现对SHA-1的攻击,这表明它可能不够安全,不能持续使用schneier.美国国家标准与技术研究院建议联邦机构应停止使用SHA1-1进行需要抗冲击的应用,并且必须在2010 NIST之后使用SHA-2 .

因此,如果您正在寻找简单快速的解决方案来检查文件的完整性(防止损坏),或者出于性能方面的一些简单缓存目的,您可以考虑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
Run Code Online (Sandbox Code Playgroud)

有关:


Fra*_*ois 6

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

只需要快速轻便的校验和即可使用它.CRC用于以太网.

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


Dav*_*ett 5

只使用CRC如果计算资源非常紧张(即一些嵌入环境)或需要存储/传输许多的输出值和空间/带宽是紧(如结直肠癌通常是32位,其中一个MD5输出是128位,SHA1 160位和其他SHA变体,最多512位).

永远不要使用CRC进行安全检查,因为CRC非常容易"伪造".

即使是偶然的错误检测(而不是恶意变化检测),散列也比简单的CRC好.部分原因是简单的方法来计算一个CRC(部分是因为CRC值比普通的散列输出通常短所以有一个更小范围的可能值),它是更可能的是,在一个情况下有两个或更多的错误,一个错误将掩盖另一个错误,所以尽管有两个错误你最终得到相同的CRC.

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

  • 如果您使用正确的多项式,CRC 将捕获所有意外的数据更改。如果恰好更改了正确的多个位,则会错过 1/2^32 更改。 (2认同)
  • 绝对不同意这一点。CRC 错误多项式经过精心选择,以便在某些情况下能够可靠地检测 1、2、3、5 和高达 11 位的突发错误。加密哈希纯粹是统计性的,因此您必须使用较大的摘要值。8-32 位对于加密哈希摘要来说是不现实的,而且 CPU 周期和门的成本也毫无意义。如果您从事嵌入式系统工作,这绝对不是一个值得考虑的答案。唯一不使用 CRC 的情况是您必须应对聪明的对手场景。 (2认同)

Joh*_*ght 5

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

  • @supercat - 我真的不相信这实际上是一个问题。如果一个文件包含一个 crc32 头,它是文件其余部分的 crc32,那么当文件更新时,crc32 头中的每一位将有大约 50% 的机会不同。标题中的更改应遵循相当随机的分布。我看不出这将如何导致 CRC32(header + data) 始终相同,或者以任何方式不依赖于文件的数据部分。 (2认同)

小智 5

让我们从基础开始。

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

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

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

此外,如果我进行 10mbps 传输,那么数据包被破坏的可能性恰好绕过 crc32 并继续沿目的地并执行。让我们说在 10mbps 我得到10 个错误\秒。如果我将其提高到 1gbps,现在我每秒会收到1,000 个错误。如果我每秒 ram 达到 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 本身在大型、标量企业环境中按照当今的标准并不是一个很好的错误检查协议;普通用户的硬盘驱动器可以拥有超过 10 万个文件,而一家公司的文件共享可以拥有数千万个。哈希空间与文件数量的比率太低了。CRC32 的计算成本很低,而 MD5 则不然。

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

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