当前位置: 代码迷 >> 综合 >> GB/T 36624-2018《可鉴别的加密机制》笔记——2. 机制1:Key Wrap
  详细解决方案

GB/T 36624-2018《可鉴别的加密机制》笔记——2. 机制1:Key Wrap

热度:53   发布时间:2024-01-12 01:25:15.0

说明:以下章节写为第6章是为了和标准GB/T 36624-2018的章节对应

6. 机制1——Key Wrap

密钥封装是为了对密钥进行保护,比如密钥存储在不太安全的存储设备中,或者密钥需要在网络中传输。

  • 2001年,NIST发布了AES Key Wrap Specification。
  • 2002年,IETF在RFC 3394中也描述了密钥封装算法AES-KeyWrap Algorithm,电信行业协会发布了使用TDES的密钥封装算法。
  • 2008年,美国标准认可委员会(Accredited Standards Committee X9, Inc.)发布了金融服务业的密钥封装算法。
  • 2009年,ISO/IEC 发布了ISO/IEC 19772-2009,其中描述了密钥封装算法。
  • 2009年,RFC 5649 描述了带填充的密钥封装算法。
  • 2012年,NIST SP 800-38F描述了AES KW、AES KWP(带填充的密钥封装算法)和TDES的TKW。
  • 2018年,我国发布GB/T 36624-2018,修改后采用ISO/IEC 19772-2009。

参考文献

  1. Key Wrap - Wikipedia, the free encyclopedia, http://en.wikipedia.org/wiki/Key_Wrap
  2. NIST Special Publication 800-38F: Recommendation for Block Cipher Modes of Operation Methods for Key Wrapping, December 2012.
  3. J. Schaad and R. Housley, Advanced Encryption Standard (AES) Key Wrap Algorithm, RFC 3394, September, 2002.
  4. R. Housley and M. Dworkin, Advanced Encryption Standard (AES) Key Wrap with Padding Algorithm, RFC 5649, August, 2009.
  5. 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.
  6. 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.

6.1 密钥封装概况

按NIST SP800-38F,密钥封装有三种

表 6.1 三种密钥封装方案

方案

KW

KWP

TKW

方案说明

基于AES等算法

不使用填充

基于AES等算法

使用填充

基于TDES算法

不使用填充

NIST SP800-38F

采用

采用

采用

ISO/IEC 19772-2009

采用

×

×

GB/T 36624-2018

采用

×

×

下面描述了所有的三个方案。如果只涉及GB/T 36624-2018,可只参见KW方案。

6.2 KW方案——AES/SM4密钥封装,不填充

KW的加密KW-AE(P)和解密KW-AD(C)。

6.2.1 加密算法KW-AE(P)

加密C = KW-AE(P)

输入:明文P

输出:密文C

1. ICV1 = 0xA6A6A6A6A6A6A6A6.

2. S = ICV1 || P.

3. Return C = W(S).

6.2.2 解密算法KW-AD(C)

解密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).

6.2.3 RFC 3394对KW的描述

RFC 3394KW采用一种便于软件实现的描述方式。

输入:

  1. 明文 P = P1||P2||...||Pn,n个64-bit
  2. 密钥 K (KEK).

输出:

  1. 密文 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]

6.3 KWP方案——AES/SM4密钥封装,带填充

带填充的加密KWP-AE(P)和带填充的解密KWP-AD(C)。

6.3.1 加密算法KWP-AE(P)

加密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。

6.3.2 解密算法KWP-AD(C)

解密P = KWP-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 = MSB8×Plen(LSB64×(n-1)(S)).

6.4 TKW方案——TDES密钥封装,不填充

这个和KW其实是一样的,只有一下几个地方有区别:

  1. 使用的密码算法不一样:KW采用AES;TKW采用TDES
  2. 分组大小不一样导致半分组大小不一样:KW半分组大小64bit;TKW半分组大小32bit。

详细流程可辅助参见KW。

注意:TKW没有加填充的所谓TKWP算法。

6.5 模块W

C = W(S)模块

准备:

  1. K(即KEK)
  2. 128-bit 分组密码CIPH.

输入:

  1. S,长度为n×64bit,n ≥ 3.

输出

  1. 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

(2.1) At = MSB64(CIPHK(At-1 || R2t-1)) ? [t]64;

(2.2) For i = 2, …, n-1: Rit = Ri+1t-1;

(2.3) Rnt = LSB64(CIPHK (At-1 || R2t-1)).

3. 输出结果

C1 = As.

For i = 2, …, n : Ci = Ris.

Return C1 || C2 || … || Cn.

图 6.2 W的示意图

(W的第2步需要执行6(n-1)次,在图中为绿色部分执行6次。)

其中迭代器的示意图如下:

图 6.3 W的迭代器的示意图

6.6 模块W-1

S = W-1(C)模块

准备:

  1. K(即KEK)
  2. 128-bit 分组密码CIPH的逆函数CIPH-1

输入:

  1. C,长度为n×64bit,n ≥ 3.

输出

  1. 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.

6.7 测试数据

  1. AES Key Wrap测试数据
  • NIST SP 800-38F里面没有测试数据。
  • 可以在RFC 3394和RFC 5649里面查。
  1. SM4 Key Wrap测试数据
  • GB/T 36624-2018 附录C.2。
  相关解决方案