代码猴子的指导密码散列为基于内容的寻址

Keeping track of large blocks of content using hash values only can be a a way to save bandwidth and build exciting new applications. Follow some important rules to use hashes correctly and securely.

开场白

It was 1996, the bandwidth between Australia and the rest of the world was miserable, and Andrew Tridgell had a problem. He wanted to synchronize source code located in Australia with source code on machines around the world, but sending patches was annoying and error-prone, and just sending all the files was painfully slow. Most people would have just waited a few years for trans-Pacific bandwidth to improve; instead Tridgell wrotersync的,第一个已知的实例基于内容寻址(也被称为内容寻址存储,或比较,通过哈希),创新最终波及到软件,如BitTorrent的,git和许多文档存储产品在市场上。

如果使用得当,基于内容的寻址将大大减少带宽使用、简化代码并提高安全性。但在没有意义的情况下使用,它会降低性能,增加带宽使用,并产生新的安全风险。弄清楚什么时候基于内容的寻址是好的,什么时候是非常、非常糟糕的,需要同时了解系统编程和数学。程序员该怎么做?在本文中,我们将用任何程序员(甚至一些管理者)都能理解的语言来阐述这些考虑因素。

基于内容的寻址:基础

Let's start with an example problem. Say you have an MP3 music collection, and your friend sends you a link to a new MP3 but doesn't give you the title. If it's already in your collection, you don't want to bother downloading and storing a second copy, so you want to quickly find out if it is identical to one of your other MP3s. If you only have a few MP3s, you'll just directly compare the new MP3 to each of your existing MP3s. This takes an amount of time proportional to the number of MP3s you already have, and if you have a lot of MP3s (and we know you do), it will run too slowly and you'll look for a smarter algorithm. A method for quickly finding a particular item that is nearly as old as computer science is called the hash table. There are a thousand variations on the hash table, but we'll describe a very simple example, and then use this to understand the tradeoffs of content-based addressing.

而不是与其他所有MP3整个MP3直接比较,我们可以运行一个函数,它的MP3数据作为其输入,输出基于输入一个固定大小的签名。我们的目标是产生类似的数字照片的缩略图 - 签名没有在原来的所有信息,但它是一个有用的提示,以什么整个文件中包含。例如,我们可以只XOR在一起,每4字节加在一起 ​​- CRC32的哈希函数的核心。Hash函数的设计生成这些签名或哈希值。相同的输入将始终具有相同的哈希值,反之,不同的散列值将总是具有不同的输入。所以,与其比较所有文件的数据,你会保护你已经拥有了MP3音乐的哈希值的表。然后,你可以问你的朋友给你新的MP3的CRC32并在哈希表中查找。如果没有与该散列值的一个MP3,那么你知道你没有朋友的MP3,这是值得的下载。

哈希冲突

如果新的MP3的哈希值在数据库中匹配一个已经会发生什么?而同一输入总是具有相同的散列值,不同的输入可以具有相同的散列值 - 散列冲突。例如,由两个32位数字0x12340000和0x00005678的输入的4个字节的XOR将是0×12345678,和的0x12345678的4个字节的XOR和00000000也将是0×12345678。因为输入的数目是无限的,并且散列值的数量是有限的,碰撞是不可避免的。事实上,一些你自己的MP3可能已经发生碰撞的哈希值。对付这种最简单的方法就是让哈希表中的每个条目有相同的散列值,并指出了其整个数据一起的MP3列表。当你找到两个MP3的散列值相同,则比较全的文件,看看他们是否真的是相同的,或者只是有相同的哈希值。现在,而不是与每个文件进行比较,你只能与具有相同的哈希值的几档比较MP3 - 而不是直接使用的每一个文件比较要快得多。

有趣的部分来了。有时,将文件与另一个文件进行比较(哪怕是一次)的成本也高得吓人,例如,当文件位于由低带宽网络分隔的不同计算机上时—假设您在南极科考站和你的朋友的MP3必须通过被流淌共享卫星链路以每秒几千比特。(或者,也许你只是还在拨号上网)。如果你把她送你的MP3的哈希值,而你却没有任何文件与相同的散列,你就知道这是值得下载MP3。问题是,当哈希相匹配到数据库中的一个现有的MP3 - 你怎么知道他们是否是相同的MP3没有缓慢而痛苦下载新的MP3和比较呢?Hash函数有冲突,这是不争的事实。但是,如果你能找到,几乎从未有过冲突的哈希函数,那么你可以,具有非常高的概率,可以肯定的是,如果哈希是相同的,他们所代表的文件也是相同的。如果该可能性高的话,你会感到安全的假设碰撞永远不会在实践中发生(勇敢地接受从未听到HI-LAR-I-OU中古怪的Al Yankovic的歌曲风险)。

输入加密哈希函数

幸运的是,抗冲突的散列函数(简单地说,很难找到具有相同输出的输入)已经被开发用于另一个目的——它们被称为加密散列函数,用于消息身份验证、数字签名、隐藏密码等。作为程序员,我们可以“借用”这些函数并将它们用于其他目的。所以现在你检测两个MP3是否相同的算法非常简单:计算并存储你所有MP3的加密哈希值。当你想知道你朋友的MP3是否是新的,你需要它的加密哈希值,然后将其与所有其他MP3的哈希值进行比较。如果它与任何现有的MP3相同,你假设它是同样的MP3,不用下载或储存。否则,你就开始下载,在研究站外为企鹅拍照。

这,概括地说,就是被称为各种基于内容寻址(CBA),比较,通过哈希(CBH),或内容寻址存储(CAS)。刚计算的一块数据(常常在比粒度整个文件更小)的加密散列,并使用所得到的散列值作为数据的地址。除了节省网络带宽,CBA消除了自上而下的地址分配框架的需求 - 每个人都计算相同的地址,而不必跟其他人 - 这是对等网络网络,如BitTorrent和分布式哈希表有用。它还简化了实施 - 节电状态是可选的,因为所有的地址可以从内容本身进行再生。

基于内容的处理也会有严肃的道nsides, depending on the application and the state of cryptographical research. First, cryptographic hashes are expensive to compute, so in many applications where the cost to transfer or compare data is low, CBA will only slow down the application. If you wanted to compare MP3s on your local hard drive, more mundane techniques, such as traditional hash tables, would be much faster than CBA in most cases. Second, the collision-resistance of a cryptographic hash function degrades over time - the cryptographic hash function that was collision-resistant when the program was first written will no longer be collision-resistant in a few years, after other cryptographers figure out how to find hash collisions quickly (hence, the term "collision-resistant" rather than "collision-free").

In the rest of this article, we'll first review cryptographic hash functions, examining their origin, computational cost, mathematical properties, and "life cycle" as they transition from newly proposed to reliably collision-resistant to broken. Then we'll explore in detail how to judge when content-based addressing will improve an application, and what effect the breaking of the chosen cryptographic hash function will have on the application. With this information under your belt, you can confidently judge when to use content-based addressing.

对于程序员加密散列函数

在这一节中,我们将对密码散列函数的各个方面进行一个简单的概述,这些方面与使用基于内容寻址的程序员最为相关。对于那些对更深入的潜水感兴趣的人,请参见进一步阅读section. A wealth of detail is available on the web these days, including most publications and pre-prints, and of course, there's always应用密码学(虽然它的严重过期。当涉及到加密散列函数和许多松树为第三版)。

大多数程序员都熟悉以加密方式对文档进行签名的思想—您可以使用加密算法来生成使用文档作为输入的签名。其他人可以通过正确的密钥验证您的签名。问题是,签名通常是一个非常缓慢和昂贵的计算,与输入的长度成正比。与其签署整个文档,不如签署一个短的、固定大小的文档签名。对于每个人来说,在给定原始文档的情况下,该签名必须易于计算,但同时对于任何人来说,很难找到另一个具有相同签名的文档(用技术术语来说,是第二个图像前阻力)。还应该很难找到具有给定签名的文档(图像前抵抗),或者具有相同签名的任何一对文档(永远抵抗碰撞)。

加密散列函数被设计来填补这个和类似的需求。在其设计的主要权衡,因为可见的程序员,主要有:

  • 计算复杂度:Too simple, and the hash is easily broken. Too complex, and the hash takes too long to calculate.
  • Size of output:太小了,蛮力攻击是太容易了。过大,存储和发送哈希值的成本过大。

通常,加密哈希函数越好,哈希值越大,计算时间越长。用于检测随机损坏的哈希函数通常速度更快,输出更短。

计算成本

为了大致了解计算加密散列需要多少CPU时间,让我们对MD5进行一次高级的了解。(MD5已经被完全破坏了,但这是一个很好的例子。)Dan Kaminsky在MD5被认为是有害的某天:

在所谓的Merkle-Damgard结构中,MD5以长度为128位的任意初始状态开始。512位的输入数据被“搅动”到这个128位的状态,结果是一个新的、大规模洗牌的128位值。512个以上的位不断地被搅动,反复搅动,直到没有更多的数据。在数据流中附加64位以上,以显式地反映正在散列的数据量,如果需要,则使用另一轮MD5进行散列(如果在前一轮中没有足够的空间散列到该64位中),并且在所有搅拌完成后的最后128位值命名为MD5散列。

The stirring operation involves 64 rounds of operation on each 512 bits of the message (technically, 4 rounds of 16 operations each). The output of each round feeds into the next round - that is, the rounds can't be easily parallelized. Newer, more modern hash functions often use 80 or more rounds of mixing. The overall message is that a cryptographic hash function involves a significant computational cost and multiple operations for every block of data processed.

Mathematics and cryptographic hash functions

素数始终是一个素数,并在数学知识没有提前永远不会改变。但作为密码改善散列函数的碰撞性随时间而变化。加密散列函数,是在心脏,人类的技术,发明了人类混淆其他人通过目前的技术和数学知识的限制。(如果你怀疑这一点,问自己,当全世界的加密社区停止考虑SHA-0单向功能 - 当美国国家安全局做了。)

虽然密码散列函数是数学函数,但它们的抗冲突特性并没有得到数学证明,并且在散列被破坏时,常常被举例证明是不正确的。以下是Bruce Schneier关于单向函数(包括加密散列函数)的看法,见第29页应用密码学:

相关:
1个2个4个 第1页
第1页共4页
IT薪资调查:结果是