国密消息鉴别码学习笔记 ——含GB/T 15852和HMAC(第2章 基于分组密码的MAC)
国密消息鉴别码学习笔记
——含GB/T 15852和HMAC
摘要:本文档对我国标准规定的消息鉴别码的生成算法进行了简要介绍,包括算法生成步骤,注意事项等。我国的相关标准包括GB/T 15852.1-2008、GB/T 15852.2-2012、GB/T15852.3(目前为草稿)。
关键词:消息鉴别码,MAC,HMAC,杂凑算法,哈希算法,HASH,分组密码,消息填充。
2. 基于分组密码的MAC
2.1 整体架构
基于分组密码的MAC算法共六种,都按以下几个流程执行(流程图如下)。
图2.1基于分组密码的MAC算法流程
1) 数据填充(三种方案);
2) 第一个块的处理,也叫初始变换(两种方案);
3) 中间块的处理(CBC-MAC);
4) MAC输出,也叫输出变换(三种方案);
基于分组密码的MAC有六种算法。
l 六种算法的数据填充方式未做硬性规定,可选择三种中的任意一种。
l 算法1—算法4是初始变换与输出变换的组合。
l 算法5(算法6)分别是两个并行的算法1(算法4)的MAC值做异或。当然并行MAC必须用不同的KEY。
l 其中某些算法可能涉及**派生,但标准未对**派生算法做硬性规定。
l 若需截断,则截获高位数据。
标准描述道:“算法4提供了一种改进的增加**长度的方法,强烈建议用户采用这个MAC算法4和填充方式3。”六种算法的详细配置如下表。
表2.1基于分组密码的MAC算法的配置情况
MAC算法 (六种方案) |
数据填充 (三种方案) |
初始变换 (两种方案) |
中间块处理 (一种方案) |
输出变换 (三种方案) |
算法1 | 任选 | 初始1 | CBC-MAC | 输出1 |
算法2 | 任选 | 初始1 | CBC-MAC | 输出2 |
算法3 | 任选 | 初始1 | CBC-MAC | 输出3 |
算法4 | 任选 | 初始2 | CBC-MAC | 输出2 |
算法5 | 任选 | 两个算法1的MAC结果异或 | ||
算法6 | 任选 | 两个算法4的MAC结果异或 |
2.2 数据填充
以下三种方案都是保证填充后的长度为分组长度n的整数倍。
填充后的数据按分组长度分割为多个块。
2.2.1 数据填充方案1
l 消息右侧填充比特零(可以不添加)。
l 空串需添加n个0。
l 对简单伪造攻击不安全。
填充数据:padding=0...00
填充后的消息:MSG|| 0...00
2.2.2 数据填充方案2
l 消息右侧先填充一个比特1,再填充比特0(可以不添加比特0)。
填充数据:padding=10...00
填充后的消息:MSG|| 10...00
2.2.3 数据填充方案3
l 先在消息右侧填充比特0(可以不添加比特0),保证填0后的长度为分组长度n的整数倍,
l 再在消息左侧添加消息长度MSG_LEN(n比特,大端表示)。
填充数据:左侧为MSG_LEN,右侧为0...00
填充后的消息:MSG_LEN|| MSG || 10...00
注:如果在计算MAC前不能知道完整消息的长度,则填充方案3不可用。
2.3 初始变换
初始变化对分割得到的第一个块进行处理,其结果类似后续CBC_MAC的IV。如果没后续块,则不做CBC_MAC。
2.3.1 初始变换方案1
输入:D1(第一个块)、K(**)
输出:H1= ENCK(D1)
2.3.2 初始变换方案2
输入:D1(第一个块)、K(**)、K**(另一个**)
输出:H1= ENCK**( ENCK(D1) )
【注:需要两个**】
2.4 输出变换
2.4.1 输出变换方案1
输入:Hq(最后一个块的MAC)
输出:H= Hq(恒等变换)
【注:无需**】
2.4.2 输出变换方案2
输入:Hq(最后一个块的MAC)、K*(**)
输出:H1= ENCK*(Hq)
【注:**是K*】
2.4.3 输出变换方案3
输入:Hq(最后一个块的MAC)、K(**)、K*(另一个**)
输出:H1= ENCK (DECK*(Hq) )
【注:先用K*解密,然后用K加密】
2.5 六种算法
标准描述道:“算法4提供了一种改进的增加**长度的方法,强烈建议用户采用这个MAC算法4和填充方式3。”
六种算法的详细配置表如下。
表2.2基于分组密码的MAC算法的配置情况
MAC算法 (六种方案) |
数据填充 (三种方案) |
初始变换 (两种方案) |
中间块处理 (一种方案) |
输出变换 (三种方案) |
算法1 | 任选 | 初始1 | CBC-MAC | 输出1 |
算法2 | 任选 | 初始1 | CBC-MAC | 输出2 |
算法3 | 任选 | 初始1 | CBC-MAC | 输出3 |
算法4 | 任选 | 初始2 | CBC-MAC | 输出2 |
算法5 | 任选 | 两个算法1的MAC结果异或 | ||
算法6 | 任选 | 两个算法4的MAC结果异或 |
2.5.1 算法1
输入**:K。
诱导**:无。
执行步骤:
CBC-MAC,IV为全零。
2.5.2 算法2
输入**:K。
诱导**:K**,一种生成方式K** = SKDF(K)(见2.5.7 一种**衍生算法)
执行步骤:
先对所有块做CBC-MAC(**K),
然后再对结果加密(**K**)。
注意事项:K≠K**,否则存在异或伪造攻击。
2.5.3 算法3
输入**:K和K*(K≠K*)。
诱导**:无。
执行步骤:
1. 先对所有块做CBC-MAC(**K),
2. 然后再对结果解密(**K*)后加密(**K)。
注意事项:K≠K*,否则算法3退化成算法1。
2.5.4 算法4
输入**:K和K*。
诱导**:K**,一种生成方式为K**=SKDF(K*)(见章节2.5.7)。
执行步骤:
1. 先对第一个块做两次加密(先K后K**),
2. 其结果作为IV和后续块(第二个块开始)做CBC-MAC(**K),
3. 然后再对结果加密(**K*)。
注意事项:填充后的消息至少是两个块才可用。
2.5.5 算法5
输入**:K。
诱导**:K1和K2,由K生成。
生成方式可以是K1=K,K2=SKDF(K)(见章节2.5.7)。
执行步骤: 1. 用**K1和K2分别对数据各做一次CBC-MAC(即算法1);
2. 然后将MAC值异或。
注意事项:保证K1≠K2。
2.5.6 算法6
输入**:K和K*。
诱导**:(K1, K1*)和(K2, K2*),由K和K*生成。
生成方式可为(K1,K1*)=(K,K*),(K2,K2*)≠(SKDF(K), SKDF(K*))。
执行步骤: 1.用**(K1, K1*)和(K2, K2*)分别对数据各做一次算法4,
2. 然后将MAC值异或。
注意事项: 1. 保证K1≠K1*、K2≠K2*、(K1, K1*)≠(K2, K2*);
2. 建议算法6的6个**各不相同(算法4实际使用3个**)。
2.5.7 一种**衍生算法
算法:简单**衍生算法SKDF(K)
输入:一个**K
输出:衍生的另一个**K*
步骤:从K的第一个4比特组开始,每隔4比特交替取补和不变生成K*。
2.6 测试向量
参见GB/T15852.1-2008的附录A。