计算MD5哈希值是否比SHA系列函数更节省CPU资源?

146

在“标准”笔记本电脑的x86硬件上,计算MD5哈希是否比SHA-1或SHA-2更少消耗CPU?我感兴趣的是一般信息,不具体针对某个芯片。

更新: 在我的情况下,我想计算文件的哈希。如果文件大小很重要,我们假设它是300K。


这不是对您问题的答案,但Skein的支持者提出了它的速度,并且它在目前肯定不比即将过时的MD5弱。如果您要哈希的消息非常短,则速度可能对密码哈希函数来说是一个缺点(具体而言,是其他人可以多快地实现它,而不是它在您的笔记本电脑上运行得有多快)。http://www.schneier.com/skein1.2.pdf - Pascal Cuoq
4
@Pascal:Skein 并不是 SHA-3 候选算法中最快的,尤其在 32 位平台上表现不佳。在 64 位 x86 上,Skein 的速度约为每秒 300 MB(Skein-512 比 Skein-256 稍快),与 SHA-1 相当,但在 32 位模式下,性能下降到不到每秒 60 MB,比 SHA-256 慢两倍。另一方面,SHABAL 是另一个 SHA-3 候选算法,其在 32 位和 64 位平台上都提供了类似 SHA-1 的性能。 - Thomas Pornin
7个回答

138

是的,MD5算法相对较少消耗CPU资源。在我的英特尔x86(Core2 Quad Q6600, 2.4 GHz)上,在32位模式下使用一个核心时,我得到了以下结果:

MD5       411
SHA-1     218
SHA-256   118
SHA-512    46

并且在64位模式下:

MD5       407
SHA-1     312
SHA-256   148
SHA-512   189

这里列出了每秒传输的兆字节数,针对“长”消息(即消息长度大于8 KB)。使用的是sphlib,一个C(和Java)哈希函数实现库。所有实现都来自同一作者(我),并且在优化上付出了可比较的努力;因此,速度差异可以被认为真正固有于这些函数。

作为比较,考虑到最近的硬盘将以约100 MB / s的速度运行,并且任何超过USB的设备将达不到60 MB / s。即使SHA-256在这里表现得“慢”,它也足够快用于大多数目的。

请注意,OpenSSL包括一个32位SHA-512实现,它比我的代码要快得多(但不如64位SHA-512快),因为OpenSSL实现是用汇编编写的,并使用SSE2寄存器,而这是无法在普通C中实现的。 SHA-512是这四个函数中唯一受益于SSE2实现的函数。

编辑:这个页面存档)上,可以找到许多哈希函数速度的报告(单击“Telechargez maintenant”链接)。报告是用法语编写的,但它主要由表格和数字组成,而数字是国际通用的。实现的哈希函数不包括SHA-3候选者(除了SHABAL),但我正在开发中。


2
我认为你的基准测试结果并不有用。基于等效但不完整的优化的两个算法的速度比较是无关紧要的。在现实世界中,你不会自己编写实现代码,而是使用完全经过优化的实现。应该比较的是这些实现的结果。 - Edward Brey
14
实际上,这些内容已经非常接近完全优化了。事实上,他的md5实现比OpenSSL提供的要快得多,所以并非每个实现都像你说的那样在“真实世界”中得到了优化。此外,虽然这些不是完美的(你说得没错),但在我看来它们对于这个特定问题是一个完美的答案。 - Gaspa79
我们是否可以获得有关现代CPU和算法现代实现的更新?您的答案曾经至少一次被用来证明MD5的持续使用,虽然在15年后已被证明不安全且在几年之后已经发生了预像攻击,以制作恶意PE文件,并签名使用MD5作为摘要算法,从而产生与原始签名中找到的完全相同的摘要。因此签名被移植。 MD5和随后的SHA-1已被删除以进行签名。 OP正在寻求哈希,因此即使在2010年,推荐使用MD5也不是明智的建议,在我看来。 - 0xC0000022L

67

在我的2012年款MacBook Air上(Intel Core i5-3427U,2x 1.8 GHz,2.8 GHz Turbo),SHA-1要比MD5稍微快一点(在64位模式下使用OpenSSL):

$ openssl speed md5 sha1
OpenSSL 0.9.8r 8 Feb 2011
The 'numbers' are in 1000s of bytes per second processed.
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
md5              30055.02k    94158.96k   219602.97k   329008.21k   384150.47k
sha1             31261.12k    95676.48k   224357.36k   332756.21k   396864.62k

更新:10个月后,使用相同的计算机和操作系统OS X 10.9,SHA-1算法变慢了:

$ openssl speed md5 sha1
OpenSSL 0.9.8y 5 Feb 2013
The 'numbers' are in 1000s of bytes per second processed.
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
md5              36277.35k   106558.04k   234680.17k   334469.33k   381756.70k
sha1             35453.52k    99530.85k   206635.24k   281695.48k   313881.86k

第二次更新:在OS X 10.10上,SHA-1的速度已经恢复到10.8的水平:

$ openssl speed md5 sha1
OpenSSL 0.9.8zc 15 Oct 2014
The 'numbers' are in 1000s of bytes per second processed.
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
md5              35391.50k   104905.27k   229872.93k   330506.91k   382791.75k
sha1             38054.09k   110332.44k   238198.72k   340007.12k   387137.77k

第三次更新:带有LibreSSL的OS X 10.14速度更快了(仍然在同一台机器上)。 SHA-1仍然是最快的:

$ openssl speed md5 sha1
LibreSSL 2.6.5
The 'numbers' are in 1000s of bytes per second processed.
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
md5              43128.00k   131797.91k   304661.16k   453120.00k   526789.29k
sha1             55598.35k   157916.03k   343214.08k   489092.34k   570668.37k

2
奇怪,我的电脑配置和你的一样,但是基准测试结果却相反。使用8192字节:MD5 305549.52k;SHA1 204668.57k。 - Carlos
3
嗯,我在同一台机器上与去年得到了不同的结果:md5 381756.70k,sha1 313881.86k。可能是因为升级到了10.9(OpenSSL 0.9.8y)的缘故。 - nwellnhof
9
这是一个很棒的回答,它表明你很在意。谢谢你分享,伙计。 - M at

40
作为一个花了不少时间优化MD5性能的人,我认为应该给那些未来可能会发现这篇文章的人提供更多技术解释,而不只是提供基准测试结果。
MD5比SHA1做的工作要少一些(例如,压缩轮次更少),因此人们可能认为它应该更快。然而,MD5算法主要是一个大的依赖链,这意味着它不能特别充分地利用现代超标量处理器(即展示低指令每时钟周期)。SHA1具有更多的并行性可用,因此尽管需要进行更多的“计算工作”,但在现代超标量处理器上它通常比MD5更快。
如果您在旧处理器或具有较少超标量“宽度”的处理器上进行MD5与SHA1的比较(例如基于Silvermont的Atom CPU),通常会发现MD5比SHA1更快。
SHA2和SHA3的计算密度甚至比SHA1还高,并且通常要慢得多。
其中需要注意的一件事是,一些新的x86和ARM CPU具有加速SHA1和SHA256的指令,如果正在使用这些指令,则可以显著帮助这些算法。
顺便说一句,SHA256和SHA512的性能可能会表现出类似的奇怪行为。SHA512所做的工作比SHA256多,但两者之间的一个关键区别是,SHA256使用32位字,而SHA512使用64位字。因此,在具有64位字大小的平台上,SHA512通常比SHA256更快,因为它一次处理了两倍的数据量。相反,在具有32位字大小的平台上,SHA256应该优于SHA512。
请注意,以上所有内容只适用于单个缓冲区哈希(迄今为止最常见的用例)。如果您喜欢并行计算多个哈希值,即多缓冲区SIMD方法,则行为会有所改变。

18

真正的答案是:这取决于

需要考虑几个因素,其中最明显的是:你正在运行这些算法的cpu和算法的实现。

例如,我和我的朋友都使用完全相同的openssl版本,在不同的Intel Core i7 cpu上得到略有不同的结果。

2021年更新:在Ryzen 9 3900x上运行openssl speed sha1 md5:Sha1现在比md5快2-3倍,随着数据大小的增加差异也会增加。

The 'numbers' are in 1000s of bytes per second processed.
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes  16384 bytes
md5             171084.26k   373867.24k   660204.56k   783808.17k   840138.75k   843743.23k
sha1            309769.46k   772013.89k  1523885.48k  2017251.67k  2226836.82k  2251024.61k

更新结束

我在工作中测试了一台配备Intel(R)Core(TM) i7-2600 CPU @ 3.40GHz的计算机。

The 'numbers' are in 1000s of bytes per second processed.
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
md5              64257.97k   187370.26k   406435.07k   576544.43k   649827.67k
sha1             73225.75k   202701.20k   432679.68k   601140.57k   679900.50k

他的电脑使用的是Intel(R) Core(TM) i7 CPU 920 @ 2.67GHz处理器。

The 'numbers' are in 1000s of bytes per second processed.
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
md5              51859.12k   156255.78k   350252.00k   513141.73k   590701.52k
sha1             56492.56k   156300.76k   328688.76k   452450.92k   508625.68k

我们都在运行相同的OpenSSL 1.0.1j二进制文件,这是2014年10月15日来自ArchLinux官方软件包。

我认为,由于sha1增加了安全性,CPU设计者更有可能提高sha1的速度,而且更多的程序员将致力于算法的优化,而不是md5sum。

我猜测md5总有一天会被淘汰,因为似乎它在与sha1相比没有任何优势。我还在真实文件上测试了一些情况,结果始终相同(可能受到磁盘I / O的限制)。

一个大约4.6GB文件的md5sum和sha1sum花费的时间完全相同,在许多小文件(同一目录下的488个)中也是如此。我进行了十几次测试,结果始终如一。

--

进一步调查这一点将非常有趣。我猜想周围可能有一些专家能够提供关于为什么sha1在新处理器上变得更快的有力答案。


7
你需要认真考虑购买固态硬盘 (以及/或者卸载 McAfee) :) - Maarten Bodewes
1
@owlstead 糟糕,我忘记在尝试这个操作时关闭我的 Linux 机器的“慢速模式”了。 - Johnride
5
@Johnride,不要从文件进行基准测试。从内存中的数据运行它,甚至更简单的方法是重新散列相同的值。 - Robino
2
@Robino,这就是openssl speed所做的事情,它是第一个也是最有意义的基准测试。 - Johnride
不,它并不依赖于情况。请分享您在哪里得到MD5比SHA慢的结果?这两个函数需要执行离散数量的操作,波动是CPU或实现启发式的结果。 - JJ Roman

1

MD5同样受益于SSE2的使用,看看BarsWF,然后告诉我它不行。只需要一点汇编知识,你就可以打造自己的MD5 SSE2例程。然而,对于大量吞吐量,存在一个速度与哈希期间花费的时间进行输入数据重新排列以与使用的SIMD指令兼容之间的权衡。


4
乍一看,不清楚SSE2是用来加速一个MD5线程还是将几个并行的MD5线程配对;后者对于大多数算法来说很容易实现,但这并不算得上从SSE2中获益,因为通常需要的是单个数据流。 - lapo

1

在Power9上,sha1sum比md5sum快得多。

$ uname -mov
#1 SMP Mon May 13 12:16:08 EDT 2019 ppc64le GNU/Linux

$ cat /proc/cpuinfo
processor       : 0
cpu             : POWER9, altivec supported
clock           : 2166.000000MHz
revision        : 2.2 (pvr 004e 1202)

$ ls -l linux-master.tar
-rw-rw-r-- 1 x x 829685760 Jan 29 14:30 linux-master.tar

$ time sha1sum linux-master.tar
10fbf911e254c4fe8e5eb2e605c6c02d29a88563  linux-master.tar

real    0m1.685s
user    0m1.528s
sys     0m0.156s

$ time md5sum linux-master.tar
d476375abacda064ae437a683c537ec4  linux-master.tar

real    0m2.942s
user    0m2.806s
sys     0m0.136s

$ time sum linux-master.tar
36928 810240

real    0m2.186s
user    0m1.917s
sys     0m0.268s

-2
[
Is MD5 faster or SHA1? ]

It's implementation dependent:

|*|
[
Theoretically the MD5 algorithm would do less work than SHA1, but the design of MD5 itself determined that the algorithm cannot effectively exploit computation parallelism (i.e. cannot effectively utilize a multi-processor system; or processors that utilize instruction-level parallelism). While SHA1 would provide better opportunity for so.

This is part of the reason why in some implementations SHA1 would outperform MD5. ]

|*|
[
There are also processors that provide dedicated hardware acceleration support for SHA1.

When properly utilized, such implementations tend to easily outperform software based MD5 implementations:

[ Quote dr-js @ CE 2021-01-28 10:31 UTC:
https://security.stackexchange.com/a/95697

2021 update with OpenSSL 1.1.1d: now we see md5 is often slower on newer CPU, and for larger chunks:

[
## PC i7-1165G7 @ 2.80GHz (2020)
OpenSSL 1.1.1d  10 Sep 2019 / built on: Mon Dec  7 20:44:45 2020 UTC
type      16 bytes    64 bytes    256 bytes   1024 bytes   8192 bytes  16384 bytes
md5     189018.70k  418310.85k   712090.28k   890189.14k   956293.12k   962560.00k
sha1    287134.62k  746529.17k  1474064.38k  1973607.08k  2197842.60k  2192179.20k
sha256  222301.71k  603962.47k  1213340.33k  1665262.59k  1849016.32k  1847388.84k

## Server AMD EPYC 7571 (2018)
OpenSSL 1.1.1d  10 Sep 2019 / built on: Mon Dec  7 20:44:45 2020 UTC
type      16 bytes    64 bytes    256 bytes   1024 bytes   8192 bytes  16384 bytes
md5      93668.33k  213979.18k   378971.56k   467472.38k   501205.67k   504064.68k
sha1    165020.82k  442991.72k   888443.48k  1188591.62k  1319236.95k  1330080.43k
sha256  142886.55k  375612.63k   791567.70k  1095950.34k  1234381.48k  1246827.86k

## Server E5-2682 v4 @ 2.50GHz (2016)
OpenSSL 1.1.1d  10 Sep 2019 / built on: Mon Dec  7 20:44:45 2020 UTC
type      16 bytes    64 bytes    256 bytes   1024 bytes   8192 bytes  16384 bytes
md5     101505.24k  207422.92k   393158.83k   453332.99k   527085.34k   490711.72k
sha1     98091.83k  249828.79k   389640.36k   675694.25k   686966.33k   721021.61k
sha256   55421.86k  130103.33k   251929.17k   302571.86k   296977.81k   338439.56k
] ]

Worth noticing that even SHA-256 could be faster than MD5 in such cases. ]


To put it in a simple (though not so accurate) statement:

|*| For high-end processors, SHA1 tends to be faster.
|*| For low-end processors, MD5 would be faster.


[ Quote Nyan @ CE 2020-12-10 10:18 UTC:
https://dev59.com/I3E85IYBdhLWcg3wikO-#64928816

Note that all of the above only applies to single buffer hashing (by far the most common use case). If you're fancy and computing multiple hashes in parallel, i.e. a multi-buffer SIMD approach, the behaviour changes somewhat. ]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接