MAC计算方法

MAC域(128域)为按照DES算法计算MAC得到的8字节二进制数据的前半部分(4字节二进制数),表示成16进制字符串形式(8个16进制字符)。具体如下:
参与报文校验码(MAC)的数据由三部分产生:初始数据,原始数据,补位数据。
MAC算法如下:
1)算法定义:采用DES CBC算法。
2)初始数据:0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00。
3)原始数据:

4)补位数据:若原始数据不是8的倍数,则右补齐0x00。若原始数据为8的整数倍,则不用不起0X00。

5)密    钥:MAC密钥。
MAC的产生由以下方式完成:(最后一组数据长度若不足8的倍数,则右补齐0x00;若数据长度为8的整数倍,则无需补充0x00)。
MAC签名计算流程图:


MAC加密与C兼容的JAVA代码

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;


import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;


public class MacEcbUtils {


private final static String DES = "DES";
private final static String CIPHER_ALGORITHM = "DES/ECB/NoPadding";


/**
* 加密

* @param src
*            数据源
* @param key
*            密钥,长度必须是8的倍数
* @return 返回加密后的数据
* @throws DesException
*/
public byte[] encrypt(byte[] src, byte[] key) {
// DES算法要求有一个可信任的随机数源
SecureRandom sr = new SecureRandom();
try {
// 从原始密匙数据创建DESKeySpec对象
DESKeySpec dks = new DESKeySpec(key);
// 创建一个密匙工厂,然后用它把DESKeySpec转换成
// 一个SecretKey对象
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
SecretKey securekey = keyFactory.generateSecret(dks);
// Cipher对象实际完成加密操作,NoPadding为填充方式 默认为PKCS5Padding
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
// 用密匙初始化Cipher对象
cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);
// 现在,获取数据并加密
// 正式执行加密操作
return cipher.doFinal(src);
} catch (NoSuchAlgorithmException e) {
// LOG.error("算数错误", e);
} catch (InvalidKeyException e) {
// LOG.error("无效key错误", e);
} catch (InvalidKeySpecException e) {
// LOG.error("无效key戳无", e);
} catch (NoSuchPaddingException e) {
// LOG.error("填充错误", e);
} catch (IllegalBlockSizeException e) {
// LOG.error("非法数据块", e);
} catch (BadPaddingException e) {
// LOG.error("错误的填充", e);
}
return null;
}


/**
* mac计算,数据不为8的倍数,需要补0,将数据8个字节进行异或,再将异或的结果与下一个8个字节异或,一直到最后,将异或后的数据进行DES计算

* @param key
* @param Input
* @return
*/
public byte[] clacMac(byte[] key, byte[] data) {


byte[] IV = new byte[8];


for (int i = 0; i < data.length;) {
IV[i & 7] ^= data[i];
++i;
if (((i % 8) == 0) || (i == data.length)) {
IV = encrypt(IV, key);
}
}


return IV;
}


public String bytesToHexString(byte[] bArray) {
StringBuffer sb = new StringBuffer(bArray.length);
String sTemp;
for (int i = 0; i < bArray.length; i++) {
sTemp = Integer.toHexString(0xFF & bArray[i]);
if (sTemp.length() < 2)
sb.append(0);
sb.append(sTemp.toUpperCase());
}
return sb.toString();
}


public String calcMacStr(String macKey, String macStr) {
byte[] key = macKey.getBytes();
byte[] data = macStr.getBytes();
byte[] macValue = clacMac(key, data);
String macValueStr = bytesToHexString(macValue).substring(0, 8);
return macValueStr;
}

public static void main(String[] args) {
String key = "12345678";
String context = "helloworld";
System.out.println(new MacEcbUtils().calcMacStr(key, context));
}
}

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值