HMAC-based Extract-and-Expand Key Derivation Function (HKDF)
Abstract
该文档描述了一个简单的基于HMAC的密钥导出方法,它可以用来在不同的协议和应用中构建早不同的block。
KDF被设计用来满足不同的应用和需求,并且被用来当做hash函数。
Status of This Memo
略
Copyright Notice
略
1.Introduction
KDF是密码学系统中必要的组件。它的目的是把一个key拓展成多个从密码学角度来上说是安全的key。
这篇文章定义了一种简单的基于HMAC的的HKDF,我们称之为HKDF。
这篇文章的目的是描述一种KDF来阻止其他的KDF实现。但是并不是强制现有的协议使用该KDF。
HKDF根据 extract-then-expand 设计模式,即KDF有2大模块。
第一个阶段是将输入的key material进行"extracts",得到固定长度的key,然后第二阶段就是
将这个key"expands"成多个附加的伪随机的key。
在许多应用中,输入的key material并不需要离散均匀的。攻击者可能会知道部分
的key material 或者修改部分的key material 。因此,"extract"的目标是把一个大的key material变成
一个小的key。有些应用中,输入的key material已经是一个很好的伪随机数。
extract流程不是必须的,所以expand流程可以独立的使用extract流程不是必须的,所以expand流程可以独立的使用。
第二步,expand这个key,使之变成期望长度的的key。输出的key的长度和个数,取决于指定的加密算法。
2. HMAC-based Key Derivation Function (HKDF)
2.1. Notation
HMAC的两个参数,第一个是key,第二个是data。data由好几个元素组成,我们一般用 | 来表示,例如:
HMAC(K, elem1 | elem2 | elem3)
2.2. Step 1: Extract
HKDF-Extract(salt, IKM) -> PRK
变量:
Hash HASH函数; HashLen 表示这个HASH函数的输出字节数。
输入:
salt 可选的值,如果没有指定,则使用HashLen个0代替;
IKM 输入的keying material
输出:
PRK a pseudorandom key (HashLen字节大小)
PRK如下计算:
PRK = HMAC-Hash(salt, IKM)
2.3. Step 2: Expand
HKDF-Expand(PRK, info, L) -> OKM
变量:
Hash HASH函数; HashLen 表示这个HASH函数的输出字节数。
输入:
PRK 至少HashLen字节长度的pseudorandom key(通常由extract流程导出)
info 可选的值,可以是""
L 期望输出的字节数(长度<=255*HashLen)
输出:
OKM 输出的keying material (L字节)
OKM 如下计算:
N = ceil(L/HashLen)
T = T(1) | T(2) | T(3) | ... | T(N)
OKM = first L octets of T
where:
T(0) = empty string (zero length)
T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
...
3. Notes to HKDF Users
这节包含了HKDF使用的一些准则,更多的细节请参考 https://eprint.iacr.org/2010/264
3.1. To Salt or not to Salt
HKDF的定义允许使用待随机值salt和不带随机值的操作。这是为了兼容没有salt的应用程序。
但是我们需要强调的是,使用salt能够显著加强HKDF,ensuring independence between different uses of the
hash function, supporting “source-independent” extraction, and
strengthening the analytical results that back the HKDF design.
随机的salt和输入的keying material有2点不同,首先他是不保密的,其次他可以复用。
所以很多应用程序可以使用salt。例如使用HKDF刷新熵池的伪随机数生成器可以使用固定的salt,而不需要保密这个salt。
In a different application domain, a key agreement protocol deriving cryptographic keys from a Diffie-Hellman exchange can derive a salt
value from public nonces exchanged and authenticated between communicating parties as part of the key agreement (this is the
approach taken in [IKEv2]).
理想情况下,salt是一个HashLen长度随机数,即使salt是一个很小的值或者熵小,也能对输出的keying material起着非常大
的作用,我们鼓励应用程序的设计者使用salt。
值得强调的是,有些应用程序使用保密的salt,这更加能够保证HKDF的安全性。
An example of such application is IKEv1 in its “public-key encryption
mode”, where the “salt” to the extractor is computed from nonces that
are secret; similarly, the pre-shared mode of IKEv1 uses a secret
salt derived from the pre-shared key.
3.2. The ‘info’ Input to HKDF
虽然info是可选的,但是对于应用程序来说,还是比较重要的。它的目的出的key material和程序上下文进行绑定。
例如,info可以是协议号,算法标识,用户标识等。这个可以保证相同IKM也能有不同的输出。对info有一个技术上的强制
规定:必须和IKM不相关。
3.3. To Skip or not to Skip
有些应用程序,输入的IKM从密码学角度来上说已经是很强的了(例如TLS的RSA秘钥交换算法的premaster secret除了开头2字节,其余的都是伪随机值)
这种情况下,可以跳过extract流程,直接使用expand流程。从另一个角度上来说,为了流程上的兼容,应用程序还需要
extract,比如IKM长度大于HMAC 的key的长度。如果IKM是DH算法的结果,那么extract不应该被跳过。因为g^(xy)本身不是离散均匀的。所以需要将
g^(xy)进行extract,然后再进行expand。
如果期望的生产的key长度L小于HashLen,有可能PRK 直接变成了OKM,这个是不建议这么用的。
3.4. The Role of Independence
略
4. Applications of HKDF
略
5. Security Considerations
略