0%

深入理解 HKDF:HMAC 密钥派生函数

介绍

在加密领域,密钥派生函数(KDF)是通过从一个初始密钥(通常称为“种子密钥”或“主密钥”)生成多个密钥的算法。HKDF(HMAC-based Key Derivation Function)是一种基于 HMAC 的密钥派生函数,它被设计用于从一个或多个输入密钥材料中生成多个安全的输出密钥。HKDF 是一个简洁且具有高度安全性的 KDF,广泛用于生成加密协议中的密钥(如 TLSIPSec 等)。

在这篇文章中,我们将深入探讨 HKDF 的原理、计算过程以及应用场景,帮助你更好地理解这个关键的密码学工具。

HKDF 的工作原理

HKDF 是一种 伪随机函数(PRF),其核心思想是从一个初始的种子密钥(或称主密钥)中生成多个密钥,并且能够提供高度的安全性。HKDF 通过两步过程实现密钥派生:提取(Extract)扩展(Expand)

1. 提取(Extract)

提取过程是将输入的密钥材料(通常是随机的)和一个盐(salt)进行处理,得到一个固定大小的伪随机输出。盐的作用是增加随机性,避免相同的输入产生相同的输出,从而增加安全性。

  • 输入

    • IKM(Input Key Material):初始密钥材料,通常是一个主密钥或其他随机数据。
    • salt(盐):一个可选的随机值,通常是由一个非秘密值(例如,固定值或随机生成的值)组成。盐可以为空,但为空时应使用特定的默认值(如全零)。
  • 输出

    • PRK(Pseudorandom Key):一个固定长度的伪随机密钥(PRK),通常使用 HMAC 作为提取过程的核心操作。

HMAC 算法将在提取过程中发挥作用,用盐和输入密钥材料(IKM)生成伪随机密钥(PRK)。

提取过程的步骤:

1
PRK = HMAC(salt || IKM)

2. 扩展(Expand)

扩展过程使用从提取步骤得到的伪随机密钥(PRK)和一些额外的参数(如输出的密钥长度和上下文信息),进一步生成所需数量的密钥。扩展步骤是通过连续应用 HMAC 来逐步生成所需的密钥。

  • 输入

    • PRK(伪随机密钥):提取过程的输出。
    • info(上下文信息):可选的额外数据(如协议标识符、会话信息等),用于区分不同的密钥生成需求。
    • L(所需密钥长度):派生出的密钥的总长度。
  • 输出

    • 一个或多个密钥,长度为 L,可以用于加密、认证等多种目的。

扩展过程通常通过不断迭代地将输出作为下次 HMAC 的输入来实现:

1
2
3
T1 = HMAC(PRK, 0x01 || info)
T2 = HMAC(PRK, T1)
T3 = HMAC(PRK, T2)

直到生成足够长度的密钥为止。每次 HMAC 的输出都会参与下一轮的计算,保证了输出的密钥具备足够的随机性和安全性。

HKDF 的详细计算过程

假设:

  • IKM(Input Key Material)= "SuperSecretKey"(种子密钥)
  • salt = "RandomSaltValue"(盐)
  • info = "ApplicationContext"(上下文信息)
  • 需要生成的密钥长度 L = 64 字节

步骤 1:提取(Extract)

首先,我们使用 HMACIKMsalt 进行计算,得到伪随机密钥(PRK)。

1
PRK = HMAC(salt || IKM)

HMAC 会根据 SHA-256 等哈希函数对 salt || IKM 进行计算,得到固定长度的输出,即伪随机密钥(PRK)。

步骤 2:扩展(Expand)

接下来,使用 PRKinfo 来生成最终的密钥。在这个过程中,我们会多次使用 HMAC 来生成所需的密钥。

  1. 初始化:

    • T1 = HMAC(PRK, 0x01 || info)
  2. 生成下一个块:

    • T2 = HMAC(PRK, T1)
  3. 如果需要继续生成更多的密钥,继续进行下去。

例如:

1
2
3
T1 = HMAC(PRK, 0x01 || info)    // 生成第一个密钥块
T2 = HMAC(PRK, T1) // 生成第二个密钥块
T3 = HMAC(PRK, T2) // 生成第三个密钥块

最终,通过连接这些块 T1, T2, T3, … 得到最终的密钥输出。如果所需的密钥长度 L 还没有满足,就继续生成更多的块,直到达到预期长度。

输出

假设我们需要生成 64 字节的密钥,可能的输出(经过扩展)可能是:

1
2
Key1 = T1[0:32]
Key2 = T1[32:64]

这些生成的密钥可以用作加密、身份验证等用途。

HKDF 的安全性

HKDF 的安全性依赖于 HMAC 的安全性和良好的输入选择。由于 HMAC 基于强大的哈希函数(如 SHA-256),并且能够有效地防止碰撞攻击、重放攻击等,它本身是非常安全的。使用高质量的盐和上下文信息(info)可以进一步增加安全性,防止生成相同的密钥。

盐的作用

盐(salt)的作用是防止相同的输入材料(IKM)生成相同的伪随机密钥(PRK)。如果不同的密钥材料没有使用盐,可能会导致同样的密钥材料每次生成相同的派生密钥,降低安全性。因此,使用随机或不可预测的盐是非常重要的。

info 参数

info 参数的作用是提供额外的上下文信息,使得即使相同的主密钥和盐被用于生成不同的密钥,也能确保它们的差异性。例如,在 TLS 中,可以将会话ID作为 info 参数,保证不同会话中生成的密钥不同。

HKDF 的应用场景

HKDF 在许多加密协议和应用中都有广泛的应用。以下是一些典型场景:

TLS/SSL:在 TLS 连接中,HKDF 用于派生会话密钥,保证每次连接都有不同的密钥,增加安全性。

IPSec:用于加密和认证的密钥派生。

密码学协议:例如,密钥交换协议中,HKDF 用于从共享密钥材料中派生密钥。

API 密钥生成:从主密钥生成多个 API 密钥,以便对不同的应用进行认证。

总结

HKDF 是一种非常强大的密钥派生函数,它结合了 HMAC 和两步提取、扩展的过程,能够生成高度安全的密钥。通过从主密钥材料中提取出伪随机密钥,再通过扩展生成所需的多个密钥,HKDF 提供了一个灵活且可靠的密钥派生方案。无论是在加密协议、密钥交换还是 API 认证中,HKDF 都是一个非常有用的工具。