【发布时间】:2011-10-26 23:14:32
【问题描述】:
创建数据的 SHA-1 哈希值大约需要多长时间和多少处理能力?这是否因原始数据大小而有很大差异?生成标准 HTML 文件的哈希会比字符串“blah”花费更长的时间吗? C++、Java 和 PHP 在速度上如何比较?
【问题讨论】:
-
“多长时间”完全取决于您运行它的平台。
-
你用哈希做什么?
创建数据的 SHA-1 哈希值大约需要多长时间和多少处理能力?这是否因原始数据大小而有很大差异?生成标准 HTML 文件的哈希会比字符串“blah”花费更长的时间吗? C++、Java 和 PHP 在速度上如何比较?
【问题讨论】:
你已经问了很多问题,所以希望我可以尝试依次回答每个问题。
SHA-1(以及许多其他设计为具有加密强度的散列)基于对固定大小的数据块重复应用加密或解密例程。因此,在计算长字符串的哈希值时,该算法花费的时间比计算小字符串的哈希值要多。在数学上,我们说使用 SHA-1 时散列长度为 N 的字符串的运行时间是 O(N)。因此,对 HTML 文档进行散列处理应该比对字符串“blah”进行散列处理花费更长的时间,但只是成比例地如此。执行哈希不会花费太多时间。
至于在速度方面比较 C++、Java 和 PHP,这是一个危险的领域,我的回答可能会被抨击,但一般来说 C++ 比 Java 略快,后者略比 PHP 更快。如果写得不好,用其中一种语言编写的良好哈希实现可能会大大优于其他语言。但是,您不必担心这一点。实现自己的哈希函数、加密例程或解密例程通常被认为是一个坏主意,因为它们通常容易受到side-channel attacks 的攻击,攻击者可以通过在实现中使用通常极难拥有的错误来破坏您的安全性预计。如果您想使用好的散列函数,请使用预先编写的版本。与手动操作相比,它可能更快、更安全、更不容易出错。
最后,我建议根本不要使用 SHA-1。 SHA-1 存在已知的加密弱点,您应该考虑改用强哈希算法,例如 SHA-256。
希望这会有所帮助!
【讨论】:
加密哈希函数的“速度”通常以“每字节clock cycles”来衡量。请参阅此page 以获得公认的过时比较 - 您可以看到实现和架构如何影响结果。结果差异很大,不仅因为所使用的算法,而且在很大程度上取决于您的处理器架构、实现的质量以及实现是否有效地使用了硬件。这就是为什么一些公司专注于创建特别适合于尽可能高效地执行某些加密算法的确切目的的硬件。
SHA-512 就是一个很好的例子,尽管它适用于比 SHA-256 更大的数据块,但人们可能倾向于认为它在处理较小的输入时通常应该比 SHA-256 执行得慢 - 但 SHA-512 特别好适用于 64 位处理器,有时甚至比 SHA-256 更好。
所有现代哈希算法都在处理固定大小的数据块。他们对一个块执行固定数量的确定性操作,并为每个块执行此操作,直到您最终获得结果。这也意味着您输入的时间越长,操作所需的时间就越长。从刚才解释的特性我们可以推断出操作的长度与消息的输入大小成正比。从数学上或计算机科学的角度讲,我们将其称为 O(n) 操作,其中 n 是消息的输入大小,正如 templatetypedef 已经指出的那样。
您不应该让散列的速度影响您对编程语言的选择,所有现代散列算法都非常非常快,与语言无关。尽管基于 C 的实现会比 Java 稍微好一点,Java 也可能比 PHP 稍微快一点,但我敢打赌,在实践中你不会知道其中的区别。
【讨论】:
SHA-1 按 64 字节的块处理数据。因此,散列长度为 n 字节的文件所需的 CPU 时间大致等于处理一个块所需的 CPU 时间的 n/64 倍。对于短字符串,必须先将字符串转换为字节序列(SHA-1 作用于字节,而不作用于字符);字符串 "blah" 将变为 4 或 8 个字节(如果您分别使用 UTF-8 或 UTF-16),因此它将作为单个块进行散列。请注意,从字符到字节的转换可能需要比散列本身更多的时间。
使用来自sphlib 的纯 Java SHA-1 实现,在我的 PC(x86 Core2,2.4 GHz,64 位模式)上,我可以以 132 MB/s 的带宽散列长消息(即使用单个CPU 内核)。请注意,这超过了普通硬盘的速度,因此在对大文件进行哈希处理时,磁盘可能会成为瓶颈,而不是 CPU:哈希文件所需的时间将是读取文件所需的时间 磁盘中的文件。
(此外,使用用 C 编写的本机代码,SHA-1 速度高达 330 MB/s。)
SHA-256 被认为比 SHA-1 更安全,SHA-256 的纯 Java 实现在我的 PC 上的速度为 85 MB/s,这仍然相当快。自 2011 年起,不推荐使用 SHA-1。
【讨论】: