单向散列函数(HASH函数)基本原理

Hash函数H(m)也名单向散列函数,它是现代密码学的核心。散列函数一直在计算机科学中使用,散列函数就是把可变的输入长度串转换成固定长度输出值(叫做散列值)的一种函数。而单向散列函数是在一个方向上工作的散列函数,从预映射的值很容易计算机其散列值,但要使其散列值等于一个特殊值却很难。好的散列函数也是无冲突的:难于产生两个预映射的值,使他们的散列值相同。

散列函数是公开的,对处理过程并不保密,单向散列函数的安全性是它的单向性,其输出不依赖于输入。平均而言,预映射值的单个位的改变,将引起散列值中一半位的改变。已知一个散列值,要找到预映射的值,使它的值等于已知的散列值在计算上是不可行的,可把单向散列函数看作是构成指纹文件的一种方法。如果你验证某人持有一个特定的文件(你同时也持有该文件),但你不想他将文件传给你,那么,就要通知他将该文件的散列值传给你,如果他传送的散列值是正确的,那么可以肯定他持有那份文件。散列函数可用于数字签名、消息的完整性检测、消息起源的认证检测等。常见的散列算法有MD5、SHA、Snefru和 HVAL等。

Hash是作用于一任意长度的消息M,返回一固定长度的散列值h:h=H(m)。其中h的长度为m。Hash函数主要用于封装或者数字签名的过程当中,它必须具有如下几个性质:

1.给定h,根据H(M)=h计算M在计算上是不可行的;

2.给定M,要找到另一消息M’。并满足H(m)=H(m’)在计算上是不可行的。

上述特性中的任何弱点都有可能破坏使用Hash函数进行封装或者签名的各种协议的安全性,如生日攻击。Hash函数的重要之处就是赋予M唯一的 “指纹”。如果用户A用数字签名算法H(m)进行签名,而B能产生满足H(m)=H(m’)的另一消息M’,那么B就可以声称A对M进行了签名。

Hash函数除了需要上述性质外还需要的性质有:

3.给定M,很容易计算h;

4.抗碰撞性。即随机找到两个消息M和M’,使H(m)=H(m’)在计算上不可行。

64位的Hash函数在生日攻击面前显得太小。大多数的Hash函数产生128位的散列值。这迫使试图进行生日攻击的攻击者必须对264个随机文件进行散列运算才能找到散列值相同的两个文件,因此不足以维持散列函数的安全性。NIST则在其安全散列标准 (SHS)中用的是160位的散列值。这使生日攻击更难进行,需要进行280次随机散列运算。

不难分析得出,散列值越长则安全性越好。许多实际应用的单向散列函数产生128位的散列值,如我们将要使用的MD5算法,这就使得任何想要攻击一次性函数的黑客们望而生畏,因此我们不妨考虑如何生成一个长的散列值。以下即为生成一个长散列值的法:

(1)运用单向散列函数生成一则消息的散列值。

(2)将该散列值附于消息之后。

(3)产生包含散列值和消息在内的一连串的数值的散列值。

(4)将第一步产生的散列值与第三步产生的散列值组合起来生成一个更大的散列值。

(5)重复(1)至(3)步若干次。