目录
Hash函数(也称散列函数或散列算法)的输入为任意长度的消息,而输出为某一固定长度的消息。即 Hash 函数将任意长度的消息串 M 映射成一个较短的定长消息串,记为 H。称 H(M)为消息 M 的 Hash值或消息摘要(message digest),有时也称为消息的指纹。
通常 Hash 函数应用于数字签名、消息完整性等方面。设 H 是一个 Hash 函数,x 是任意长度的二元串,相应的消息摘要为y=H(x),通常消息摘要是一个相对较短的二元串(例如 160 比特)。假设我们已经计算出了 y 的值,那么如果有人改变 x 的值为 x’,则通过计算消息摘要 y’=hash(x’),验证 y’与 y 不相等就可以知道原来的消息 x 已被改变。
通常,Hash 函数可以分为两类:
Hash 函数是为指定的消息产生一个消息“指纹”, Hash 函数通常具有以下这些性质:
Hash 函数将一个任意比特长度的输入 x 映射为固定长度为 n 的输出 H(x)。
给定 Hash 函数 H 和任意的消息输入 x,计算 H(x)是简单的。
对所有预先给定的输出值,找到一个消息输入使得它的 Hash 值等于这个输出在计算上是不可行的。即对给定的任意值y,求使得 H(x)=y 的 x 在计算上是不可行的。在密码学中,通常这一性质也称为 Hash函数的单向性。
对于任何的输入,找到一个与它有相同输出的第二个输入,在计算上是不可行的。即给定一个输入 x,找到一个 x’,使得H(x)=H(x’)成立是计算不可行的,如果单向 Hash 函数满足这一性质,则称其为弱单向 Hash 函数。
找出任意两个不同的输入 x 与 x’,使得 H(x)=H(x’)在计算上是不可行的,如果单向 Hash 函数满足这一性质,则称其为强单向Hash 函数。在网络安全中,这个性质非常重要。
攻击者可以对 Hash 函数发起两种攻击。
第一种就是找出一个 x’,使得 H(x)=H(x’)。
例如,在一个使用 Hash 函数的签名方案中,假设 s 是签名者对消息 x 的一个有效签名,s=sig(H(x))。攻击者可能会寻找一个与 x 不同的消息 x’使得 H(x)=H(x’)。如果能找到一个这样的 x’,则攻击者就可以伪造对消息 x’的签名,这是因为 s 也是对消息 x’的有效签名。Hash 函数的弱无碰撞性可以抵抗这种攻击。
攻击者可以发起另一种攻击。同样一个应用 Hash 函数的签名方案中,对手可能会寻找两个不同的消息 x 和 x’,使得 H(x)=H(x’)。然后说服签名者对消息 x 签名,得到 s=sig(H(x))。由于 s=sig(H(x’)),所以攻击者得到了一个对消息 x’的有效签名。Hash 函数是强无碰撞性可以抵抗这种攻击。
假设已经知道 A 的生日为某一天,问至少有多少个人在一起时,至少有 1/2 的概率使有一个人和 A 的生日相同?
初步理解:我们假定一年有 365 天,且所有人的生日均匀分布于 365 天中。下面我们求解所需的最少人数。
首先,有 1 人和 A 有相同生日的概率为 1/365,有不同生日的概率则为:
1-1/365=364/365
K 个人与 A 生日不同的概率应为:
K 个人至少有 1 个人与 A 的生日相同,且概率不小于 1/2 应为:
所以可得:
进一步计算可得:
即至少为 253 人。
若已知 A 的生日,则当至少有 253 个人时,才能保证有 1/2 的概率使有 1 人和 A 的生日相同。
假设一年有 365 天,每个人的生日均匀分布于 365天,那么至少有多少个人在一起是,能保证至少有 1/2 的概率存在 2 个人有相同的生日?
第 2 类生日问题也称生日悖论。
令 为 m 个人在一起,不存在相同生日的概率。根据假定,则 m-1个人中无相同生日的概率为 ,m-1 个人共有生日 m-1 天。第 m 个人与前面 m-1 人无相同生日的概率为:
也就是递推关系满足:
由此可得:
可以验证当 m≥23 时,Pm<1/2。即 23 个人在一起时,无相同生日的概率小于 1/2。反过来就是当 23 个让你在一起是,有两个人的生日相同的概率大于 1/2。这个结果挺神奇的。
哈希函数的迭代结构一般为:
目前使用的大多数Hash函数如MD5、SHA-1,其结构都是迭代型的,如上图所示。其中函数的输入M被分为L个分组,每一个分组的长度为b比特,如果最后一个分组的长度不够,需对其做填充。最后一个分组中还包括整个函数输入的长度值。这将使得攻击者的攻击更为困难,即攻击者若想成功地产生假冒的消息,就必需保证假冒消息的Hash值与原消息的Hash值相同,而且假冒消息的长度也要与原消息的长度相等。