- 密钥封装(Key Wrap)
密钥封装是为了对密钥进行保护,比如密钥存储在不太安全的存储设备中,或者密钥需要在网络中传输。
早在2001年,NIST就发布了AES Key Wrap Specification。2002年,IETF在RFC 3394中也描述了密钥封装算法AES-KeyWrap Algorithm,电信行业协会发布了使用TDES的密钥封装算法。2008年,美国标准认可委员会(Accredited Standards Committee X9, Inc.)发布了金融服务业的密钥封装算法。2009年,RFC 5649 描述了带填充的密钥封装算法。 2012年,NIST SP 800-38F描述了AES KW、AES KWP(带填充的密钥封装算法)和TDES的TKW。
NIST的这三个算法和RFC等的描述几乎完全一致。
以下描述以NIST SP 800-38F为主,结合RFC 3394和RFC 5649。
参考文献
- Key Wrap - Wikipedia, the free encyclopedia, http://en.wikipedia.org/wiki/Key_Wrap
- NIST Special Publication 800-38F: Recommendation for Block Cipher Modes of Operation Methods for Key Wrapping, December 2012.
- J. Schaad and R. Housley, Advanced Encryption Standard (AES) Key Wrap Algorithm, RFC 3394, September, 2002.
- R. Housley and M. Dworkin, Advanced Encryption Standard (AES) Key Wrap with Padding Algorithm, RFC 5649, August, 2009.
- ANSI/TIA-102.AACA-1-2002: Project 25 – Digital Radio Over-the-Air-Rekeying (OTAR) Protocol: Addendum 1 – Key Management Security Requirements for Type 3 Block Encryption Algorithms, Telecommunications Industry Association, November, 2002.
- ANS X9.102-2008, Symmetric Key Cryptography For the Financial Services Industry—Wrapping of Keys and Associated Data, Accredited Standards Committee X9, Inc., June, 2008.
- 密钥封装有三种
- KW 基于AES的密钥封装,不使用填充。
- KWP 基于AES的密钥封装,使用填充。
- TKW 基于TDES的密钥封装,不使用填充。
算法 | 明文 | 密文 | 使用模块 |
KW | 2—254-1个64bit长 | 3—254个64bit长 | W和W-1 |
KWP | 1—232-1个8bit长 | 2—232个8bit长 | W和W-1 |
TKW | 2—228-1个32bit长 | 3—228个32bit长 | TW和TW-1 |
- W
C = W(S)模块
准备:
- K(即KEK)
- 128-bit 分组密码CIPH.
输入:
- S,长度为n×64bit,n ≥ 3.
输出
- C,与S等长(长度为n×64bit,n ≥ 3)。
步骤
1. 初始化
s = 6(n-1).
S=S1 || S2 ||… || Sn . Si都是64it
A0 = S1.
For i = 2, …, n
R0i = Si.
2. 迭代
For t = 1, …, s
At = MSB64(CIPHK(At-1 || R2t-1)) ⊕ [t]64;
For i = 2, …, n-1:
Rit = Ri+1t-1;
Rnt = LSB64(CIPHK (At-1 || R2t-1)).
3. 输出结果
C1 = As.
For i = 2, …, n
Ci = Ris.
Return C1 || C2 || … || Cn.
W的示意图如下
W的示意图
W中迭代器的示意图如下:
W中迭代器的示意图
- W-1
S = W-1(C)模块
准备:
- K(即KEK)
- 128-bit 分组密码CIPH的逆函数CIPH-1
输入:
- C,长度为n×64bit,n ≥ 3.
输出
- S,与c等长(长度为n×64bit,n ≥ 3)。
步骤
1. 初始化
s = 6(n-1).
C = C1 || C2 ||… || Cn . Ci都是64bit
As = C1.
For i = 2, …, n
Rsi = Ci.
2. 迭代
For t = s, …, 1
At-1 = MSB64((CIPH-1K(At ⊕[t]64)) || Rnt);
R2t-1 = LSB64(CIPH-1K ((At ⊕[t]64) || Rnt).
For i = 2, …, n-1:
Ri+1t-1 = Rit ;
3. 输出结果
S1 = A0.
For i = 2, …, n
Si = Ri0.
Return S1 || S2 || … || Sn.
- KW
KW的加密KW-AE(P)和解密KW-AD(C)。
加密C = KW-AE(P)
输入:明文P
输出:密文C
1. ICV1 = 0xA6A6A6A6A6A6A6A6.
2. S = ICV1 || P.
3. Return C = W(S).
解密P = KW-AD(C)
输入:密文C
输出:明文P或者失败
1. ICV1 = 0xA6A6A6A6A6A6A6A6.
2. S = W-1(C).
3. If MSB64(S) ≠ICV1, return FAIL and stop.
4. Return P = LSB64(n-1)(S).
RFC 3394对KW采用一种便于软件实现的描述方式。
输入:
- 明文 P = P1||P2||...||Pn,n个64-bit
- 密钥 K (KEK).
输出:
- 密文 C = C0||C1||...||Cn,(n+1)个64-bit
步骤
1) A = IV, IV = 0xA6A6A6A6A6A6A6A6
For i = 1 to n, R[i] = P[i]
2) For j = 0 to 5 {
For i=1 to n {
B = AES(K, A || R[i])
A = MSB(64, B) ⊕ t,其中t = (n*j)+i
R[i] = LSB(64, B)
}//i
}//j
3) C[0] = A
For i = 1 to n, C[i] = R[i]
Return C = C[0] || C[1] || ... || C[n]
- KWP
带填充的KW加密KWP-AE(P)和带填充的KW解密KWP-AD(C)。
加密C = KWP-AE(P)
输入:明文P
输出:密文C
1. ICV2 = 0xA65959A6.
2.
3. PAD = 08×padlen
4. S = ICV2 || [len(P)/8]32 || P || PAD
5. If len(P) ≤ 64, return C = CIPHK(S);
else, return C = W(S).
这里的padlen是指将明文P填充为64bit的整数倍时需要填充(填充数据为全零字节)的最短字节数,可以为0。消息S表示在填充后消息的前面再加64比特的特殊消息,以保证S长度最少为一个分组大小(128bit)。如果S长度只有一个分组大小,则直接执行AES。
解密P = KW-AD(C)
输入:密文C,C = C1||C2||...||Cn, n个64-bit
输出:明文P或者失败
1. ICV2 = 0xA65959A6.
2. If n = 2, S = CIPH-1K(C); if n > 2, S = W-1(C).
3. If MSB32(S) ≠ ICV2, return FAIL and stop.
4. Plen = int(LSB32(MSB64(S))).
5. padlen = 8(n-1)-Plen.
6. If padlen <0 or padlen > 7, return FAIL and stop.
7. If LSB8×padlen(S) ≠ 08×padlen, return FAIL and stop.
8. Return P &#61; MSB8×Plen(LSB64×(n-1)(S)).
- TKW
这个和KW其实是一样的&#xff0c;只有一下几个地方有区别&#xff1a;
- 使用的密码算法不一样&#xff1a;KW采用AES&#xff1b;TKW采用TDES
- 分组大小不一样导致半分组大小不一样&#xff1a;KW半分组大小64bit&#xff1b;TKW半分组大小32bit。
详细流程可辅助参见KW。
注意&#xff1a;TKW没有加填充的所谓TKWP算法。
- 测试数据
NIST SP 800-38F里面没有测试数据&#xff1b;测试数据可以在RFC 3394和RFC 5649里面查。
LibTomCrypt目前尚不支持KeyWrap。