SHA-256的填充与迭代过程
题目描述
讲解SHA-256哈希算法的消息填充和迭代压缩过程,包括如何将任意长度输入分割为固定大小的分组,并通过轮函数逐步生成256位哈希值。重点分析填充规则、消息扩展、轮常量与逻辑函数的协作机制。
1. 算法背景
SHA-256属于SHA-2家族,输出长度为256位(32字节)。其核心结构为Merkle-Damgård构造,将输入消息经过填充后分割为512位(64字节)的分组,每个分组通过压缩函数与当前哈希值迭代计算。
2. 消息填充步骤
假设原始消息长度为 \(L\) 位(\(L \geq 0\)):
- 补位1:在消息末尾添加一个"1"位(实际操作为字节0x80),占1位。
- 补0:继续添加 \(k\) 个"0"位,使总长度满足 \(L + 1 + k \equiv 448 \pmod{512}\)。
- 附加长度:在末尾追加64位的无符号整数(大端序),表示原始消息的位长度 \(L\)。
示例:若消息为"abc"(3字节=24位):
- 原始消息:01100001 01100010 01100011(24位)
- 补位1后:01100001 01100010 01100011 10000000(32位)
- 补0至440位:需补 \(448 - (24+1) = 423\) 个0位(实际补0字节到总长度64-8=56字节)
- 附加长度:64位大端序的24(0x0000000000000018)
最终分组长度为512位,满足 \(24 + 1 + 423 + 64 = 512\)。
3. 初始化哈希值
初始化8个32位寄存器(初始哈希值 \(H^{(0)}\)),取自前8个质数的平方根小数部分前32位:
H0 = 0x6a09e667, H1 = 0xbb67ae85, H2 = 0x3c6ef372, H3 = 0xa54ff53a,
H4 = 0x510e527f, H5 = 0x9b05688c, H6 = 0x1f83d9ab, H7 = 0x5be0cd19
4. 迭代压缩过程
对每个512位分组执行以下步骤:
4.1 消息扩展
- 将分组划分为16个32位字 \(W[0]\) 到 \(W[15]\)(大端序)。
- 扩展为64个32位字 \(W[0]\) 到 \(W[63]\):
\[ W[t] = \begin{cases} W[t] & 0 \leq t \leq 15 \\ \sigma_1(W[t-2]) + W[t-7] + \sigma_0(W[t-15]) + W[t-16] & 16 \leq t \leq 63 \end{cases} \]
其中:
\(\sigma_0(x) = (x \ggg 7) \oplus (x \ggg 18) \oplus (x \gg 3)\)
\(\sigma_1(x) = (x \ggg 17) \oplus (x \ggg 19) \oplus (x \gg 10)\)
4.2 轮函数计算
- 初始化工作变量 \(a, b, c, d, e, f, g, h\) 为当前哈希值 \(H^{(i-1)}\)。
- 进行64轮运算(每轮使用常数 \(K[t]\) 和 \(W[t]\)):
\[ \begin{aligned} T_1 &= h + \Sigma_1(e) + \text{Ch}(e,f,g) + K[t] + W[t] \\ T_2 &= \Sigma_0(a) + \text{Maj}(a,b,c) \\ h &= g, \quad g = f, \quad f = e, \quad e = d + T_1 \\ d &= c, \quad c = b, \quad b = a, \quad a = T_1 + T_2 \end{aligned} \]
逻辑函数定义:
- \(\text{Ch}(x,y,z) = (x \land y) \oplus (\neg x \land z)\)
- \(\text{Maj}(x,y,z) = (x \land y) \oplus (x \land z) \oplus (y \land z)\)
- \(\Sigma_0(x) = (x \ggg 2) \oplus (x \ggg 13) \oplus (x \ggg 22)\)
- \(\Sigma_1(x) = (x \ggg 6) \oplus (x \ggg 11) \oplus (x \ggg 25)\)
4.3 更新哈希值
每处理完一个分组,更新哈希值:
\[\begin{aligned} H_0^{(i)} &= a + H_0^{(i-1)}, \quad H_1^{(i)} = b + H_1^{(i-1)}, \quad \dots, \quad H_7^{(i)} = h + H_7^{(i-1)} \end{aligned} \]
5. 最终输出
所有分组处理完成后,将 \(H_0^{(N)}\) 到 \(H_7^{(N)}\) 拼接为256位哈希值(大端序)。
关键点总结
- 填充确保消息长度为512位的整数倍,且最后64位记录原始长度。
- 消息扩展通过移位和异或操作增加随机性。
- 轮函数通过非线性逻辑函数和模加操作实现扩散和混淆。
- 初始值的设计与质数相关,避免后门嫌疑。