首页 > 技术文章 > 第二十个知识点:Merkle-Damgaard hash函数如何构造

zhuowangy2k 2020-01-31 15:25 原文

第二十个知识点:Merkle-Damgaard hash函数如何构造

这里讲的是MD变换,MD变换的全称为Merkle-Damgaard变换.我们平时接触的hash函数都是先构造出一个防碰撞的压缩函数.然后先证明这个小的,固定长度的压缩函数是安全的,然后再用它构造一个任意长度的哈希算法.虽然存在很多其它的构造方法,MD是迄今为止最常用的(至少是被用到最多的),例如MD5,SHA1,SHA2.因此是时候来了解一下它了.

安全的哈希函数?

一般来说,一个安全的哈希函数\(h\)应该是:

  • 抗原象攻击(Pre-image Resistant).给定\(h(x)\)很难计算出\(x\)
  • 第二抗原象攻击(Second Pre-image Resistant).给定\(x\),很难找出\(y\),使得\(h(x) = h(y)\).
  • 抗碰撞:很难找出\(x,y\)使得\(h(x) = h(y)\)

如果一个哈希函数是防碰撞的.它一定是第二抗原象攻击的.因此,这就是我们集中的碰撞一致性.

压缩函数

一个压缩函数\(f:\{0,1\}^n * \{0,1\}^r \rightarrow \{0,1\}^n\)是函数.就像名字一样"压缩",它会将\(n+r\)bit宽的输入压缩成\(n\)bit的输出.正如您可能期望的那样,抗冲突压缩函数是一种抗冲突的压缩函数.因此它可能是一个固定长度的hash函数,但是如果我们想让这个函数变成长度可变的,我们应该怎么办.

MD哈希函数的构造

MD构造函数提供一个方法扩展一个固定长度的压缩函数变成一个可变长度的压缩函数.使用一个压缩函数\(f\),我们会用\(n\)bit的值作为我们的内部状态,同时每次迭代给定\(r\)bit的值.为了做这件事,我们首先使用一个初始的值(IV),然后分割消息\(M\)成每块\(r\)bit,\(M= M_0M_1...M_m\).然后简单的迭代构造:

\[S_0 := IV,i = 0,...,m-1:S_{i+1} = f(S_i,M_i),h(M) := S_m \]

img

MD构造方法中最重要的就是如果压缩函数抗碰撞的,因此整个构造就是抗碰撞的(已经被Merkle证明了).这给了我们一个安全的方法从一个小的简单的密钥原语构造hash函数.

长度扩展

你可能注意到这个图有一个我没有描述的阶段:这个Finalisation阶段.这就是组织长度扩展攻击.例如,如果\(N\)是一个单一的块(ie,\(N \in \{0,1\}^r\)).如果攻击者知道\(h(M) = x\),然后我们很容易计算\(h(M||N)\).因为\(h(M||N) = f(M,N)\).因此一些finalisation函数能被用于打破这个关系.

实际上这里说的啥我没懂,但是我翻看了别的书

1557728631669

look!这里就是真正的过程,如果它的倍数不对,就是用PB,即padding.

padding的格式是:

\[PB = 100...000||<s> \]

s是块的数量,s是64bit长,也就是说最多有\(2^{64}\)个块.如果不够s那么就在后面再补一个块.

安全证明可以搜一搜,网上都能搜到.

推荐阅读