MD5 与 CRC32:哪个更适合常用?

  • 本文关键字:常用 CRC32 MD5 algorithm hash
  • 更新时间 :
  • 英文 :


最近我在某处读到,虽然CRC32和MD5都足够统一和稳定,但CRC32比MD5更有效。MD5似乎是一种非常常用的哈希算法,但如果CRC32更快/更有效的内存,那么为什么不使用它?

MD5 单向散列算法。单向哈希算法通常用于密码学,因为它们具有(每个设计)很难找到产生特定哈希值的输入的属性。具体来说,很难让两个不同的输入给出相同的单向哈希。它们通常被用作显示自生成哈希码以来没有故意更改数据量的方法。由于MD5是一个单向哈希算法,因此安全性比速度更重要。不幸的是MD5现在被认为是不安全的。

CRC32用于检测数据的意外变化,通常用于网络和存储设备中。该算法的目的不是防止故意的更改,而是捕获诸如网络错误和磁盘写错误等事故。该算法的重点在于速度而不是安全性。

摘自维基百科关于MD5的文章:

MD5是一种广泛使用的加密哈希函数

现在CRC32:

CRC是一个错误检测码

所以,正如你所看到的,CRC32 不是一个哈希算法。这意味着你不应该将它用于散列,因为它不是为此而构建的。

我认为讨论普遍使用没有多大意义,因为类似的算法用于不同的目的,每个算法都有明显不同的要求。没有一种算法是最适合通用的,相反,您应该选择最适合您特定用途的算法。

这取决于你的目标。下面是一些使用CRC32和MD5可以完成的示例:

检测重复文件

如果你想检查两个文件是否相同,CRC32校验和是一种方法,因为它比MD5更快。但是要小心:CRC只能可靠地告诉你二进制文件是否不同;它不会告诉你它们是否相同。如果两个文件的哈希值不同,它们不可能是相同的文件,因此您可以很快地将它们作为重复项拒绝。

无论你的密钥是什么,CRC32校验和将是2^32个不同的值之一。假设样本文件是随机的,两个给定文件的哈希值碰撞的概率是1/2^32。任意N个给定文件之间的碰撞概率为(N - 1)/2^32。

检测恶意软件

如果安全性是一个问题,比如下载一个文件并根据你的文件检查源的哈希值,看看二进制文件是否没有损坏,那么CRC是一个糟糕的选择。这是因为攻击者可以制作具有相同CRC校验和的恶意软件。在这种情况下,MD5摘要更安全——CRC不是为了安全而制定的。两个不同的二进制文件更有可能具有相同的CRC校验和,而不是相同的MD5摘要。

保护用户身份验证密码

同步(单向)加密通常比异步(双向)加密更容易、更快、更安全,因此它是存储密码的常用方法。基本上,密码将与其他数据(盐)组合,然后对所有这些组合数据进行哈希。随机盐极大地降低了两个密码相同的可能性。默认情况下,对于大多数算法,相同的密码将具有相同的散列,因此您必须添加自己的随机性。当然,盐必须外存。

要让用户登录,您只需获取他们在登录时提供的信息。你用他们的用户名从数据库中获取他们的盐。然后将这个盐与用户的密码结合起来,得到一个新的哈希值。如果与数据库中的匹配,则登录成功。因为你正在存储这些密码,它们必须非常安全,这意味着CRC校验和是不可能的。

加密摘要比CRC校验和的计算成本更高。此外,像sha256这样更好的散列更安全,但散列速度较慢,占用更多的数据库空间(它们的散列更长)。

CRC32和MD5之间的一个很大的区别是,通常很容易选择一个CRC32校验和,然后得出一个哈希到该校验和的消息,即使对消息施加了约束,而MD5是专门设计来使这种事情变得困难的(尽管它显示了它的年龄-现在在某些情况下这是可能的)。

如果您处于这样一种情况,即对手可能决定坐下来创建具有指定CRC32哈希值的消息负载,以模仿其他消息,或者只是使哈希表执行得非常糟糕,因为所有哈希值都相同,那么MD5将是更好的选择。(依我之见,更好的是HMAC-MD5的键值对于使用它的模块来说是唯一的,并且在它之外是未知的)。

crc用于防止随机错误,例如在数据传输中。

加密散列函数的设计是为了防止智能对手伪造消息,尽管MD5在这方面已经被打破。

实际上,CRC32 并不比MD5 快。

请看:https://3v4l.org/2MAUr

该php脚本运行几种散列算法,并测量每个算法计算散列所花费的时间。它表明MD5通常是最快的散列算法。而且,它表明在大多数测试用例中,甚至SHA1也比MD5快。

所以,无论如何,如果你想做一些快速的错误检测,或者寻找随机的变化…我总是建议使用MD5,因为它可以简单地完成所有工作。

CRC32(或CRC8,或CRC16)被用于任何目的的主要原因是它可以在硬件中廉价地实现作为检测数据"随机"损坏的手段。即使在软件实现中,它也可以作为检测硬件原因(如嘈杂的通信线路或不可靠的闪存介质)导致的数据随机损坏的一种手段。它不是防篡改的,通常也不适合测试两个任意文件是否可能相同:如果文件中的每个数据块后面紧跟着该块的CRC32(某些数据格式会这样做),那么每个块对整个文件的CRC的影响将与所有零字节的块相同,无论该块中存储了什么数据。

如果有办法快速计算CRC32,如果具有相同CRC的不同文件在其他哈希中可能不同,那么与其他校验和或哈希方法结合可能会有所帮助,反之亦然,但在许多机器上,其他校验和或哈希方法相对于它们提供的保护量可能更容易计算。

您应该使用128位长的MD5。CRC32只有32位长,它的目的是检测错误,而不是散列。如果你只需要一个32位的哈希函数,你可以选择MD5返回的32位的lsdb/msb/等等。

如果你不知道该选什么,那就选md5

不太可能引起你头痛。

它涵盖了crc32更可取的所有情况。在这些情况下,您唯一要牺牲的是效率(当数据块非常小时,可能是cup关于位的答案中所描述的)。
相反,如果您在需要md5sum的情况下选择crc32,您将牺牲更关键的东西,如安全性,在某些上下文中甚至是数据完整性。

结论:只有当你知道你在做什么时才使用CRC32。

一个人的常见是另一个人的罕见。Common的变化取决于你在哪个领域工作。

如果你正在进行非常快速的传输或为小项目计算哈希码,那么CRC更好,因为它们更快,并且为错误数据获得相同的16或32位CRC的机会很小。

如果它是兆字节的数据,例如,linux iso,那么您可能会丢失几兆字节,但最终仍然具有相同的CRC。MD5就不太可能了。因此,MD5通常用于巨额传输。它更慢,但更可靠。

基本上,如果你要做一个大的传输并在最后检查你是否有正确的结果,使用MD5。

最新更新