SHA-256的填充与迭代过程
字数 2180 2025-11-01 09:19:03

SHA-256的填充与迭代过程

题目描述
讲解SHA-256哈希算法的消息填充和迭代压缩过程,包括如何将任意长度输入分割为固定大小的分组,并通过轮函数逐步生成256位哈希值。重点分析填充规则、消息扩展、轮常量与逻辑函数的协作机制。


1. 算法背景
SHA-256属于SHA-2家族,输出长度为256位(32字节)。其核心结构为Merkle-Damgård构造,将输入消息经过填充后分割为512位(64字节)的分组,每个分组通过压缩函数与当前哈希值迭代计算。


2. 消息填充步骤
假设原始消息长度为 \(L\) 位(\(L \geq 0\)):

  1. 补位1:在消息末尾添加一个"1"位(实际操作为字节0x80),占1位。
  2. 补0:继续添加 \(k\) 个"0"位,使总长度满足 \(L + 1 + k \equiv 448 \pmod{512}\)
  3. 附加长度:在末尾追加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位记录原始长度。
  • 消息扩展通过移位和异或操作增加随机性。
  • 轮函数通过非线性逻辑函数和模加操作实现扩散和混淆。
  • 初始值的设计与质数相关,避免后门嫌疑。
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位: 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位记录原始长度。 消息扩展通过移位和异或操作增加随机性。 轮函数通过非线性逻辑函数和模加操作实现扩散和混淆。 初始值的设计与质数相关,避免后门嫌疑。