HKDF(HMAC-Based Key Derivation Function)是一种基于 HMAC(Hash-based Message Authentication Code)的密钥派生函数,用于从原始密钥材料(如共享密钥、随机数等)生成多个加密密钥(如AES加密密钥、认证密钥等),以下是其详细介绍:
### 算法原理
HKDF 基于 HMAC 构造,适用于多种应用场景,包括密码学密钥生成、随机数产生等。其主要目标是将可能具有某些安全属性(如随机性)的原始密钥材料转换为适合用于特定加密算法的一组密钥。
### 算法流程
HKDF 分为两个阶段:提取(Extract)和扩展(Expand)。
* **提取阶段** :
此阶段使用一个提取函数,将原始密钥材料(如共享密钥、随机数等)和一个可选的盐值(salt)作为输入,生成一个伪随机密钥(PRK)。提取函数通常是一个 HMAC 函数,盐值用于增加熵值和安全性。提取过程的公式为:PRK = HMAC(salt,IKM),其中 IKM 是原始密钥材料。
* **扩展阶段** :
扩展阶段使用一个扩展函数,将 PRK 和一个可选的信息(info)作为输入,生成一系列输出密钥(OKM)。信息参数用于为生成的密钥提供上下文和可区分性。扩展函数基于 HMAC 进行多次迭代,每次迭代使用不同的计数器值来生成不同的密钥材料。具体过程如下:
1. 初始化计数器 T 为一个空字符串。
2. 对于每个所需的密钥块(块大小等于 HMAC 的输出大小),执行以下操作:
* 计算 T = HMAC(PRK,T || info || [计数器]),其中“||”表示字符串拼接,计数器以字节形式表示。
* 将计算得到的 T 添加到输出密钥材料中。
3. 重复上述步骤,直到生成了足够长度的输出密钥材料。
### 算法特点
* **密钥分离** :HKDF 通过提取阶段将原始密钥材料转换为一个伪随机密钥,从而在逻辑上分离了原始密钥和生成的密钥,增加了系统的安全性。
* **密钥抽取** :提取阶段可以有效地从原始密钥材料中抽取熵值,即使原始密钥材料的质量不高,也能生成具有足够随机性的伪随机密钥。
* **密钥扩展** :扩展阶段可以生成多个不同长度的密钥,满足不同加密算法和应用场景的需求。
* **兼容性** :HKDF 兼容多种 HMAC 实现,因此具有良好的跨平台和跨系统兼容性。
### 应用场景
* **密钥派生** :在加密通信协议中,用于从共享密钥材料(如 Diffie-Hellman 密钥交换产生的共享密钥)生成多个加密密钥,如 AES 加密密钥、HMAC 密钥等。
* **随机数生成** :在需要随机数的场景中,可以利用 HKDF 从随机种子生成高质量的随机数。
* **身份认证** :在某些身份认证协议中,用于生成会话密钥等。
### 安全性考虑
* **盐值和信息参数的选择** :盐值和信息参数应具有足够的随机性和不可预测性,以防止攻击者通过猜测或暴力破解获取原始密钥材料。
* **HMAC 实现的安全性** :应使用经过验证的 HMAC 实现,并确保其正确性和安全性。
* **密钥管理** :生成的密钥应妥善保管,并在使用后及时销毁,以防止密钥泄露。
* **密钥长度和迭代次数** :应根据安全需求选择适当的密钥长度和扩展阶段的迭代次数,以确保生成的密钥具有足够的强度。
HMAC和HKDF
HKDF(HMAC-Based Key Derivation Function)和 HMAC(Hash-based Message Authentication Code)都基于哈希函数,但它们的功能和应用场景有所不同,以下是它们的主要区别:
### 定义和功能
* **HMAC** :一种基于哈希函数的消息认证码算法,用于验证消息的完整性和身份认证。它通过将密钥与消息结合,生成一个固定长度的认证码,接收方可以通过相同的密钥和哈希函数重新计算认证码来验证消息的完整性和身份。主要用于验证消息是否被篡改以及确认消息发送者的身份。
* **HKDF** :一种基于 HMAC 的密钥派生函数,用于从原始密钥材料(如共享密钥、随机数等)生成多个加密密钥(如 AES 加密密钥、认证密钥等)。其主要目标是将可能具有某些安全属性的原始密钥材料转换为适合用于特定加密算法的一组密钥。
### 算法结构和机制
* **HMAC** :使用一个密钥和一个消息作为输入,通过两次哈希函数运算生成认证码。其计算过程如下:
1. 将密钥与填充字节拼接,得到一个临时密钥。
2. 将临时密钥与消息进行 XOR 运算,得到一个中间值。
3. 对中间值进行哈希运算,得到最终的认证码。
* **HKDF** :分为提取(Extract)和扩展(Expand)两个阶段。在提取阶段,使用 HMAC 作为提取函数,将原始密钥材料和可选的盐值作为输入,生成一个伪随机密钥(PRK)。在扩展阶段,使用 HMAC 作为扩展函数,将 PRK 和可选的信息(info)作为输入,生成一系列输出密钥(OKM)。
### 应用场景
* **HMAC** :适用于需要对消息进行完整性验证和身份认证的场景,如在加密通信协议中验证消息的来源和完整性,防止消息被篡改或伪造。
* **HKDF** :适用于需要从原始密钥材料生成多个加密密钥的场景,如在加密通信协议中从共享密钥材料生成用于加密、认证、完整性验证等不同目的的密钥。
### 输出长度
* **HMAC** :输出长度由所使用的哈希函数决定,例如使用 SHA-256 时,HMAC 的输出长度为 32 字节。通常是一个固定长度的认证码。
* **HKDF** :输出长度可以灵活调整,根据需求生成不同长度的密钥序列。在扩展阶段,可以根据所需的密钥长度多次调用 HMAC 函数,将结果拼接起来得到最终的输出密钥材料。
### 安全性
* **HMAC** :安全性依赖于所使用的哈希函数和密钥的强度。如果哈希函数是安全的,并且密钥具有足够的随机性和长度,那么 HMAC 可以提供强大的消息认证功能。但其主要用于消息认证,不能直接用于密钥派生。
* **HKDF** :通过提取和扩展阶段,增加了密钥派生过程的安全性和灵活性。在提取阶段,即使原始密钥材料的质量不高,也可以通过盐值和 HMAC 的处理生成具有足够随机性的伪随机密钥。在扩展阶段,通过信息参数和 HMAC 的多次迭代,可以生成多个不同长度的密钥,满足不同加密算法和应用场景的需求。
### 算力消耗
* **HMAC** :相对简单,计算速度快,适合在资源受限的设备上使用。因为它只涉及两次哈希函数运算,且哈希函数本身通常经过优化,具有较高的效率。
* **HKDF** :由于需要进行提取和扩展两个阶段的处理,计算量相对较大。在提取阶段,需要进行一次 HMAC 运算;在扩展阶段,根据所需的密钥长度,可能需要进行多次 HMAC 运算。因此,HKDF 的算力消耗高于 HMAC。
HMAC
HMAC(Hash-based Message Authentication Code)是一种基于哈希函数的消息认证码算法,用于验证消息的完整性和身份认证。它广泛应用于需要防止消息被篡改或伪造的场景,是一种非常重要的密码学工具。以下是HMAC的详细介绍:
### 基本概念
HMAC 是一种密钥相关的哈希运算的消息认证码(MAC)机制,其设计基于加密哈希函数(如MD5、SHA-1、SHA-256等),通过将密钥与消息结合,生成一个固定长度的认证码,接收方可通过相同密钥和哈希函数重新计算认证码来验证消息是否被篡改或伪装。
### 工作原理
HMAC 通过两次哈希函数运算实现,基本步骤如下:
1. **密钥处理**:将密钥与填充字节拼接,得到两个临时密钥。
2. **第一轮哈希运算**:将第一个临时密钥与消息进行 XOR 运算,然后对结果进行哈希运算。
3. **第二轮哈希运算**:将第二个临时密钥与第一轮哈希运算的结果进行 XOR 运算,再进行哈希运算,得到最终的认证码。
其计算公式如下:
HMAC(K, M) = H((K' ^ opad) || H((K' ^ ipad) || M)))
其中:
- K 是密钥
- M 是消息
- H 是哈希函数
- ipad 是内填充字节(0x36重复的字节)
- opad 是外填充字节(0x5C重复的字节)
- K' 是密钥 K 的处理版本,若 K 的长度大于哈希函数块大小,则 K' 是 H(K);否则 K' 是 K 用零字节填充到块大小
### 算法步骤
以常见的实现步骤为例:
1. **密钥填充**:
- 如果密钥长度大于哈希函数的块大小(如对于SHA-256,块大小为64字节),则先对密钥进行哈希运算,得到一个固定长度的临时密钥。
- 将临时密钥(或原始密钥,如果其长度小于等于块大小)用零字节填充到块大小,得到一个固定长度的密钥。
2. **内填充和外填充**:
- 创建两个临时密钥:opad密钥和ipad密钥。
- opad密钥是将密钥的每个字节与0x5C进行异或运算得到的结果。
- ipad密钥是将密钥的每个字节与0x36进行异或运算得到的结果。
3. **第一次哈希运算**:
- 将ipad密钥与消息拼接,然后对拼接后的数据进行哈希运算,得到中间哈希值。
4. **第二次哈希运算**:
- 将opad密钥与中间哈希值拼接,然后对拼接后的数据进行哈希运算,得到最终的HMAC值。
### 选择哈希函数
HMAC的安全性依赖于所使用的哈希函数。常见的哈希函数包括:
- **MD5**:虽然计算速度快,但已被证明存在碰撞攻击风险,不建议用于需要高安全性的场景。
- **SHA-1**:已被证明存在潜在的碰撞攻击风险,逐渐被更安全的哈希函数所取代。
- **SHA-256**:是SHA-2家族的一部分,具有较高的安全性,适用于大多数需要高安全性的场景。
- **SHA-3**:较新的哈希函数标准,提供更强的安全性,适用于对安全性要求极高的场景。