跳到主要内容

2. HMAC 的定义 (Definition of HMAC)

HMAC 的定义需要一个密码散列函数 (我们用 H 表示) 和一个密钥 K。我们假设 H 是一个密码散列函数, 其中数据通过在数据块上迭代基本压缩函数来散列。我们用 B 表示此类块的字节长度 (对于上述所有散列函数示例, B=64), 用 L 表示散列输出的字节长度 (MD5 的 L=16, SHA-1 的 L=20)。认证密钥 K 的长度可以是最多 B (散列函数的块长度) 的任意长度。使用长于 B 字节的密钥的应用程序将首先使用 H 对密钥进行散列, 然后将结果 L 字节字符串用作 HMAC 的实际密钥。在任何情况下, K 的最小推荐长度为 L 字节 (作为散列输出长度)。有关密钥的更多信息, 请参见第 3 节。

我们定义两个固定且不同的字符串 ipad 和 opad 如下 ('i' 和 'o' 是内部和外部的助记符):

ipad = 字节 0x36 重复 B 次
opad = 字节 0x5C 重复 B 次

要计算数据 text 上的 HMAC, 我们执行:

H(K XOR opad, H(K XOR ipad, text))

即:

  1. 在 K 的末尾追加零以创建 B 字节字符串 (例如, 如果 K 的长度为 20 字节且 B=64, 则 K 将追加 44 个零字节 0x00)
  2. 将步骤 (1) 中计算的 B 字节字符串与 ipad 进行 XOR (按位异或)
  3. 将数据流 'text' 追加到步骤 (2) 产生的 B 字节字符串
  4. 将 H 应用于步骤 (3) 生成的流
  5. 将步骤 (1) 中计算的 B 字节字符串与 opad 进行 XOR (按位异或)
  6. 将步骤 (4) 的 H 结果追加到步骤 (5) 产生的 B 字节字符串
  7. 将 H 应用于步骤 (6) 生成的流并输出结果

为了说明目的, 附录中提供了基于 MD5 的示例代码。