cevalokas

personal website

Not because they are easy, but because they are hard.


哈希算法

目录

哈希算法是一种将输入数据(通常是任意长度的消息)转换为固定长度的字符串或数字的方法。这种转换过程通常是通过一系列复杂的数学运算实现的。哈希算法广泛应用于数据加密、数据校验、文件完整性验证等领域。

哈希算法的工作原理

哈希算法的核心在于将输入的任意长度数据,通过一系列不可逆的数学操作,生成一个固定长度的输出。这种输出通常被称为哈希值或摘要。哈希算法具有以下几个重要特性:

  1. 确定性:相同的输入总是会生成相同的输出。这意味着,对于任何给定的输入数据,无论你执行多少次哈希运算,结果都是相同的。

  2. 不可逆性:哈希算法的运算过程是单向的,从哈希值几乎不可能反推出原始输入数据。即使拥有相同的哈希算法和结果,也无法直接得知输入数据的内容。

  3. 抗碰撞性:不同的输入数据不应该生成相同的哈希值。这一特性对于确保数据唯一性非常重要,尽管实际应用中,总有可能存在极少量的碰撞,但好的哈希算法应该极大地减少碰撞的概率。

  4. 敏感性:输入的微小改变会导致输出哈希值的巨大变化。例如,将一个文件的某个字节由 0 改为 1,生成的哈希值将与原始文件完全不同。这一特性在数据完整性验证中非常有用。

常见的哈希算法

目前,常用的哈希算法有以下几种:

  • MD5(Message Digest Algorithm 5):产生128位的哈希值,曾经广泛用于校验数据完整性。然而,随着时间推移,MD5被发现存在严重的安全漏洞,尤其是易于产生碰撞,因此在安全领域逐渐被弃用。

  • SHA-1(Secure Hash Algorithm 1):产生160位的哈希值,相比MD5安全性有所提升。然而,随着计算能力的提升,SHA-1也被发现存在安全风险,已不再推荐用于敏感数据的哈希操作。

  • SHA-256:属于SHA-2系列,产生256位的哈希值,目前被广泛应用于数据加密和数字签名等领域。SHA-256被认为是目前较为安全的哈希算法之一。

1. MD5(Message Digest Algorithm 5)

公式步骤

  • 输入消息 $M$ 被填充到长度为 $512$ 的倍数,分为 $L$ 个块,每个块 $512$ 位。

  • 初始的4个32位寄存器 $A_0$, $B_0$, $C_0$, $D_0$ 被设定为固定常数值。

  • 对于每个消息块 $M_i$,MD5 进行四轮处理,每轮有16次操作。每次操作使用以下函数之一:

    • \[F(B, C, D) = (B \land C) \lor (\neg B \land D)\]
    • \[G(B, C, D) = (B \land D) \lor (C \land \neg D)\]
    • \[H(B, C, D) = B \oplus C \oplus D\]
    • \[I(B, C, D) = C \oplus (B \lor \neg D)\]
  • 每轮的数学表达式为:

    \[A = B + \left( (A + F(B, C, D) + M[k] + T[i]) \ll s \right)\]

    其中,$M[k]$ 是当前消息块中的数据,$T[i]$ 是固定表中的常数,$s$ 是向左旋转的位数。

  • 最终的哈希值是所有块处理完毕后的 $A$, $B$, $C$, $D$ 的组合。

2. SHA-1(Secure Hash Algorithm 1)

公式步骤

  • 输入消息 $M$ 被填充到长度为 $512$ 的倍数,分为 $L$ 个块,每个块 $512$ 位。

  • 初始5个32位寄存器 $H_0$, $H_1$, $H_2$, $H_3$, $H_4$ 被设定为固定常数值。

  • 对于每个消息块 $M_i$,SHA-1 进行80轮处理。每轮使用以下函数之一:

    • \[Ch(x, y, z) = (x \land y) \oplus (\neg x \land z)\]
    • \[Maj(x, y, z) = (x \land y) \oplus (x \land z) \oplus (y \land z)\]
    • \[Par(x, y, z) = x \oplus y \oplus z\]
  • 每轮的数学表达式为:

    \[T = (H_{i-1} \ll 5) + f(H_{i-2}, H_{i-3}, H_{i-4}) + H_{i-5} + W[t] + K[t]\]

    其中,$W[t]$ 是消息块的扩展数据,$K[t]$ 是固定表中的常数。

  • 最终的哈希值是所有块处理完毕后的 $H_0$, $H_1$, $H_2$, $H_3$, $H_4$ 的组合。

3. SHA-256

公式步骤

  • 输入消息 $M$ 被填充到长度为 $512$ 的倍数,分为 $L$ 个块,每个块 $512$ 位。

  • 初始8个32位寄存器 $H_0$, $H_1$, $H_2$, $H_3$, $H_4$, $H_5$, $H_6$, $H_7$ 被设定为固定常数值。

  • 对于每个消息块 $M_i$,SHA-256 进行64轮处理。每轮使用以下函数之一:

    • \[Ch(x, y, z) = (x \land y) \oplus (\neg x \land z)\]
    • \[Maj(x, y, z) = (x \land y) \oplus (x \land z) \oplus (y \land z)\]
    • \[\Sigma_0(x) = ROTR^2(x) \oplus ROTR^{13}(x) \oplus ROTR^{22}(x)\]
    • \[\Sigma_1(x) = ROTR^6(x) \oplus ROTR^{11}(x) \oplus ROTR^{25}(x)\]
    • \[\sigma_0(x) = ROTR^7(x) \oplus ROTR^{18}(x) \oplus SHR^3(x)\]
    • \[\sigma_1(x) = ROTR^{17}(x) \oplus ROTR^{19}(x) \oplus SHR^{10}(x)\]
  • 每轮的数学表达式为:

    \(T_1 = H_{i-7} + \Sigma_1(H_{i-2}) + Ch(H_{i-3}, H_{i-4}, H_{i-5}) + K[t] + W[t]\) \(T_2 = \Sigma_0(H_{i-1}) + Maj(H_{i-2}, H_{i-3}, H_{i-4})\)

    其中,$W[t]$ 是消息块的扩展数据,$K[t]$ 是固定表中的常数。

  • 最终的哈希值是所有块处理完毕后的 $H_0$, $H_1$, $H_2$, $H_3$, $H_4$, $H_5$, $H_6$, $H_7$ 的组合。

    哈希算法的应用场景

  1. 数据校验和完整性验证:在文件传输或存储过程中,哈希算法用于生成文件的哈希值。接收方可以通过计算接收到的文件哈希值,并与发送方提供的哈希值进行比较,来验证文件是否被篡改。

  2. 密码存储:在用户认证系统中,哈希算法用于将用户的密码哈希后存储在数据库中。即使数据库被攻击者获取,由于哈希值不可逆,攻击者也无法轻易还原用户的明文密码。

  3. 数字签名:数字签名技术通过哈希算法确保消息的完整性和不可否认性。发送方对消息生成哈希值并使用私钥进行签名,接收方使用公钥验证签名,从而确认消息的来源和完整性。