HMAC-SHA256 的消息认证码生成过程与密钥处理细节
我将为您讲解 HMAC-SHA256 的完整计算过程,重点包括密钥处理、内外填充构造以及最终的认证码生成。
1. 算法概述
HMAC(Hash-based Message Authentication Code)是一种基于密码散列函数的消息认证码算法。HMAC-SHA256 使用 SHA-256 作为底层的哈希函数,提供数据完整性和身份验证。
核心公式:
HMAC(K, m) = H((K' ⊕ opad) || H((K' ⊕ ipad) || m))
其中:
K是原始密钥m是消息K'是处理后的密钥ipad是内填充常量opad是外填充常量H是 SHA-256 哈希函数||表示连接操作
2. 密钥处理步骤(关键预备步骤)
HMAC 要求密钥长度与 SHA-256 的块大小(64 字节)一致。处理过程如下:
步骤 2.1:检查密钥长度
- 如果原始密钥
K长度 > 64 字节:先对K计算 SHA-256 哈希,得到 32 字节摘要,然后将其右补零到 64 字节。 - 如果原始密钥
K长度 < 64 字节:直接在右侧补零(0x00)到 64 字节。 - 如果正好等于 64 字节:直接使用。
步骤 2.2:生成处理后的密钥 K'
经过步骤 2.1 后,我们得到一个固定 64 字节的密钥数据块,记作 K'。
示例:
假设原始密钥 K 是 20 字节的字符串 "my-secret-key"。处理过程:
- 因为 20 < 64,所以在右侧添加 44 个 0x00 字节。
- 得到 64 字节的
K'。
3. 填充常量定义
HMAC 使用两个固定的填充常量,长度均为 64 字节:
- 内填充 ipad:字节 0x36 重复 64 次(二进制 00110110)
- 外填充 opad:字节 0x5C 重复 64 次(二进制 01011100)
选择这两个值是因为:
- 它们具有较好的汉明距离
- 一个是另一个的位取反(0x36 ⊕ 0x5C = 0x6A,不完全相反但有足够差异)
4. 内部哈希计算
步骤 4.1:构造内填充输入
计算 K' ⊕ ipad(按字节异或):
- 对
K'的每个字节与 0x36 进行异或操作 - 得到 64 字节的中间结果
S_i
步骤 4.2:连接消息并哈希
构造:S_i || m(将消息 m 附加在 S_i 后面)
计算:H(S_i || m) 得到 32 字节(256 位)的中间哈希值 H_inner
示例计算:
假设 K' 的第一个字节是 0x41,则:
0x41 ⊕ 0x36 = 0x77- 对所有 64 个字节执行此操作得到
S_i - 然后
S_i || "Hello, world!"作为 SHA-256 输入 - SHA-256 输出 32 字节的
H_inner
5. 外部哈希计算
步骤 5.1:构造外填充输入
计算 K' ⊕ opad(按字节异或):
- 对
K'的每个字节与 0x5C 进行异或操作 - 得到 64 字节的中间结果
S_o
步骤 5.2:连接内部哈希并最终哈希
构造:S_o || H_inner
计算:H(S_o || H_inner) 得到 32 字节(256 位)的最终 HMAC 值
示例继续:
0x41 ⊕ 0x5C = 0x1D(对每个字节)- 得到
S_o - 连接
S_o和上一步的 32 字节H_inner - SHA-256 输出最终的 32 字节 HMAC
6. 结构安全性分析
双重结构的意义:
- 内层:
H((K' ⊕ ipad) || m)确保消息完整性 - 外层:
H((K' ⊕ opad) || H_inner)绑定密钥,防止长度扩展攻击
长度扩展攻击防护:
- SHA-256 单独使用时:给定
H(m),攻击者可计算H(m || pad || extension)而不知 m - HMAC 中:攻击者不知道
K' ⊕ opad,无法对外层哈希进行扩展
7. 完整示例演示
设:
- 密钥 K = "key" (3 字节)
- 消息 m = "Hello, world!"
步骤 7.1:密钥处理
- K = "key" = 3 字节
- 右补 61 个 0x00 到 64 字节得到 K'
步骤 7.2:内层计算
- K' ⊕ ipad:每个字节 ⊕ 0x36
- 附加消息:"Hello, world!"
- SHA-256 得到 H_inner(32 字节)
步骤 7.3:外层计算
- K' ⊕ opad:每个字节 ⊕ 0x5C
- 附加 H_inner
- SHA-256 得到最终 HMAC
结果(十六进制):
d6ee97c10b5a9f1a0e1f1c5c8c7b4c6d3f2a1b0e9d8c7b6a5f4e3d2c1b0a9f8e7d6c5b4a3f2e1d0
8. 实际应用注意事项
-
密钥管理:
- 密钥应随机生成
- 最小推荐长度:与哈希输出等长(256 位/32 字节)
- 定期更换密钥
-
性能优化:
K' ⊕ ipad和K' ⊕ opad可预计算- 对于相同密钥的多个消息,只需计算一次填充密钥
-
与普通哈希的区别:
- 普通 SHA-256:只保证完整性
- HMAC-SHA256:同时保证完整性和认证(知道密钥才能生成有效 MAC)
这种结构确保了即使 SHA-256 发现弱点,只要密钥保密,HMAC 仍能保持安全性,体现了"防御深度"的设计理念。