SHA-256哈希算法的填充与迭代过程
题目描述
SHA-256是一种广泛使用的密码学哈希算法,可将任意长度的输入数据转换为固定长度(256位)的哈希值。其核心步骤包括消息填充和迭代压缩。本题要求详细解释这两个过程的设计原理与计算步骤。
1. 消息填充(Padding)
SHA-256要求输入消息的长度必须是512位的倍数,因此需要对原始消息进行填充:
步骤分解:
-
添加比特“1”:在消息末尾追加一个比特“1”(二进制
0x80,即十六进制的80,因为SHA-256按字节处理)。
示例:若消息为"abc"(二进制01100001 01100010 01100011),填充后变为01100001 01100010 01100011 10000000。 -
补“0”比特:在比特“1”后补足够多的“0”,直到消息长度满足:
\[ \text{最终长度} \equiv 448 \pmod{512} \]
即最后512位分组的后64位留作记录原始消息长度。
- 附加长度值:在最后64位中,以大端序(Big-Endian)写入原始消息的比特长度(不含填充部分)。
示例:"abc"长度为24比特(3字节),其64位二进制表示为000...00011000(前56位为0)。
填充示例(消息"abc"):
- 原始消息:
01100001 01100010 01100011(24比特) - 填充后:
01100001 01100010 01100011 10000000 [补448比特模512的条件] 000...000 (423个0) 00011000 (64位的长度值) - 最终得到1个512位的分组(若消息更长,可能需多个分组)。
2. 迭代压缩(Iterative Compression)
填充后的消息被切分为多个512位分组,每个分组通过压缩函数处理,并与前一次的哈希结果迭代运算。
初始哈希值(IV)
SHA-256的初始哈希值\(H^{(0)}\)是8个32位常量,取自前8个质数的平方根的小数部分前32位:
\[H^{(0)} = [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19] \]
压缩函数核心步骤(以单个分组为例)
- 消息扩展(Message Schedule):
- 将512位分组划分为16个32位字 \(W_0, W_1, ..., W_{15}\)。
- 扩展生成64个32位字 \(W_0 \dots W_{63}\):
\[ W_t = \sigma_1(W_{t-2}) + W_{t-7} + \sigma_0(W_{t-15}) + W_{t-16}, \quad \text{其中 } t=16 \dots 63 \]
这里 $ \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) $(`>>>`表示循环右移,`>>`表示逻辑右移)。
- 迭代更新状态:
- 初始化8个寄存器 \(a, b, c, d, e, f, g, h\) 为当前哈希值 \(H^{(i-1)}\)。
- 进行64轮循环(每轮使用扩展字 \(W_t\) 和常量 \(K_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}(e,f,g) = (e \land f) \oplus (\neg e \land g) $(选择函数)
- $ \text{Maj}(a,b,c) = (a \land b) \oplus (a \land c) \oplus (b \land c) $(多数函数)
- $ \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) $
- 更新哈希值:
将本轮结果与初始哈希值相加(模 \(2^{32}\)):
\[ H^{(i)} = [a+H_0, b+H_1, ..., h+H_7] \]
3. 最终输出
处理完所有分组后,将最后的 \(H^{(n)}\) 拼接为256位哈希值。
安全性关键点:
- 填充规则确保攻击者无法构造碰撞(如长度扩展攻击需规避)。
- 迭代结构使雪崩效应扩散到整个哈希值。
通过以上步骤,SHA-256实现了对任意输入的高效、抗碰撞的哈希计算。