IC卡交易中MAC的计算方式

image

报文鉴别码(MAC)的计算方法

1.基于分组算法的MAC

依照ISO/IEC 9797-1规范,使用密钥长度为128位的对称加密算法采用CBC模式对任意长度的报文计算8字节MAC值。(就是采用3DES的CBC模式)

MAC算法参数说明
M 明文消息
C 密文消息
Mac 消息认证码
K MAC密钥
IV 初始向量
Ek(M) 使用密钥K对M进行加密
Dk© 使用密钥K对C进行解密

算法说明:

  1. 在明文M后附加0x80,然后在右端填充最少的0x00,使得填充后消息M = (M||80||00||00||…||00)的长度为8的整数倍。然后将M分为8字节(文档上是16字节,但我认为是不正确的)的块M1,M2,M3,…,Mn;
  2. 将密钥K分为8字节的两部分KL和KR,初始向量IV = (00||00||00||00||00||00||00||00);
  3. 计算过程如下,C0 = IV, Ci = Ekl(Mi ^ Ci-1) i=1,2,…,n
  4. 最后一块数据再作如下计算Mac = Ekl(Dkr(Cn))

对上面3,4步骤说明如下,Mi异或C(i-1),结果采用KL进行DES加密处理,以此循环,得到最后的Cn,采用KR对Cn进行DES解密处理,然后再采用KL进行DES加密处理,得到的结果就是8字节的MAC值。

2.基于SM4的MAC

SM4和上面类似,不过其采用的是SM4算法,采用密钥长度为128位的对称加密算法采用CBC模式对任意长度的报文计算16字节MAC值。

MAC算法参数说明
M 明文消息
C 密文消息
Mac 消息认证码
K MAC密钥
IV 初始向量
Ek(M) 使用密钥K对M进行加密
Dk© 使用密钥K对C进行解密

其算法作下说明:

  1. 在明文M后附加0x80,然后在右端填充最少的0x00,使得填充后消息M = (M||80||00||00||…||00)的长度为16的整数倍。然后将M分为16字节的块M1,M2,M3,…,Mn;
  2. 初始向量IV = (00||00||00||00||00||00||00||00||00||00||00||00||00||00||00||00);
  3. 计算过程如下,C0 = IV, Ci = Ek(Mi ^ Ci-1) i=1,2,…,n
  4. 取最后一块左8字节作为MAC:Mac = LEFT(Cn)

3.基于HASH算法的HMAC

HMAC算法依照FIPS规范,使用摘要算法生成HMAC

HMAC算法参数说明
ipad 填充字符串,内容为:8位字节0x36 重复64次
opad 填充字符串,内容为:8位字节0x5c,重复64次
text 所输入的需要计算MAC的数据,不包括填充字符串
K MAC密钥
t 所得MAC的字节长度
Hash安全哈希算法 使用密钥K对M进行加密
Dk© 使用密钥K对C进行解密

其计算公式如下:

MAC(text)t = HAMC(K,text)t = Hash((K0 ^ opad) || Hash((K0 ^ ipad)||text))

对上面公式说明如下:

  1. 若K = 64 ,令K0 = K,跳转到步骤4
  2. 若K > 64 , 令K0 = Hash(K),跳转到步骤4
  3. 若K < 64 , 则在K末尾补字节0x00产生64字节K0
  4. K0与ipad异或产生64字节字符串:K0 ^ ipad
  5. 将text追加到步骤4的末尾:(K0 ^ ipad) || text
  6. 将步骤5得到的字符串进行哈希得到:Hash((K0 ^ ipad) || text)
  7. K0与opad异或:K0 ^ opad
  8. 将步骤6产生的结果追加到步骤7的结果末尾:(K0 ^ opad) || Hash((K0 ^ ipad) || text)
  9. 对步骤8的结果做哈希得到:Hash((K0 ^ opad) || Hash((K0 ^ ipad) || text))
  10. 步骤9得到的哈希值作为MAC值。

4.基于SM3的HMAC

HMAC算法依照FIPS规范,使用SM3算法生成HMAC

HMAC算法参数说明
ipad 填充字符串,内容为:8位字节0x36 重复32
opad 填充字符串,内容为:8位字节0x5c,重复32
text 所输入的需要计算MAC的数据,不包括填充字符串
K MAC密钥
t 所得MAC的字节长度
Hash安全哈希算法 使用密钥K对M进行加密
Dk© 使用密钥K对C进行解密

其计算公式如下:

MAC(text)t = HAMC(K,text)t = Hash((K0 ^ opad) || Hash((K0 ^ ipad)||text))

对上面公式说明如下:

  1. 若K = 32 ,令K0 = K,跳转到步骤4
  2. 若K > 32 , 令K0 = Hash(K),跳转到步骤4
  3. 若K < 32 , 则在K末尾补字节0x00产生32字节K0
  4. K0与ipad异或产生32字节字符串:K0 ^ ipad
  5. 将text追加到步骤4的末尾:(K0 ^ ipad) || text
  6. 将步骤5得到的字符串进行哈希得到:Hash((K0 ^ ipad) || text)
  7. K0与opad异或:K0 ^ opad
  8. 将步骤6产生的结果追加到步骤7的结果末尾:(K0 ^ opad) || Hash((K0 ^ ipad) || text)
  9. 对步骤8的结果做哈希得到:Hash((K0 ^ opad) || Hash((K0 ^ ipad) || text))
  10. 步骤9得到的哈希值作为MAC值。

[参考]

  1. [中国金融集成电路(IC)卡规范 第16部分]
作者: Peter
出处: http://codefunny.github.io/
本文基于
署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名 Peter(包含链接)。