大侠们,求mac算法的java实现,搜了半天只有c的。
能支持银联ansi 9.9 mac 算法参与消息校验码(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)。
能支持银联ansi 9.9 mac 算法参与消息校验码(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)。
一般是在数据的尾部增加一个信息摘要,一般用MD5、SHA、CRC32等算法计算。
MD5、SHA可以参考javax.security中的加密部分。
boolean CheckMac (byte [] data, int macOffset)
{
byte [] orgMac = new byte [data.length - macOffset] ;
ArrayCopy (orgMac, data, macOffset, orgMac.length) ;
byte [] mac = ComputeMac (data, 0, macOffset) ; ...计算的mac
// 比较mac是否相等
for (int i = 0 ; i < orgMac.length ; i ++)
if (orgMac [i] != mac [i]) return false ; return true ;
}
http://it.wikipedia.org/wiki/Modalit%C3%A0_di_funzionamento_dei_cifrari_a_blocchi#Cipher_Block_Chaining_.28CBC.29从这里看,基本就是个采用 CBC 模式的 DES 算法,而且还是个变了种的填充方式。
public class AnsiiX99MAC {
static{
Security.addProvider(new BouncyCastleProvider());
}
public static void main(String[] args) {
//zak(mackey)
byte[] MACKEY = ConvertUtil.strToBcd("8F37EADF07CB5232");
//待计算数据
byte[] data = ConvertUtil.stringToBytes("0200702004C000C010532000008600898000005018600000000000000100000047021F9106323330303030303133303130303230303030303036313000000000000000000047525108980001FFFFFFFF00008600898000005018741ECF4A010000010001863C00000064020000000000017132B6B800114000000800000003303030","iso8859-1");
//进行分组
int group = (data.length + (8 - 1)) / 8;
//偏移量
int offset = 0 ;
//输入计算数据
byte[] edata = null;
for(int i = 0 ; i < group; i++){
byte[] temp = new byte[8];
if(i != group - 1){
System.arraycopy(data, offset, temp, 0, 8);
offset += 8;
}else{//只有最后一组数据才进行填充0x00
System.arraycopy(data, offset, temp, 0, data.length - offset);
} if(i != 0){//只有第一次不做异或
temp = XOR(edata,temp);
}
edata = desedeEn(MACKEY,temp);
}
System.err.println(ConvertUtil.bcdToStr(edata));
}
public static byte[] XOR(byte[] edata, byte[] temp) {
byte [] result = new byte[8];
for (int i = 0 , j = result.length ; i < j; i++) {
result [i] = (byte) (edata[i] ^ temp[i]);
}
return result;
}
public static byte[] desedeEn(byte[] key,byte[] data){
byte[] result = null;
try {
SecretKey secretKey = getSecretKeySpec(key);
Cipher cipher = Cipher.getInstance("DES/CBC/NoPadding","BC");
cipher.init(Cipher.ENCRYPT_MODE, secretKey,new IvParameterSpec(new byte[8]));//初始化项目为0
result = cipher.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
private static SecretKey getSecretKeySpec(byte[] keyB) throws NoSuchAlgorithmException, InvalidKeySpecException {
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("Des");
SecretKeySpec secretKeySpec = new SecretKeySpec(keyB,"Des");
return secretKeyFactory.generateSecret(secretKeySpec);
}
}9.9的标准在国内还是有不少变种的,记不太清你这是那的标准了,给你一个国际标准的实现...
2、然后用MACKEY:07B0AB16A18AAB08 ,初始数据:0000000000000000 ,mab的HEX数据:30383130822000008200080004000000000000013038313031303132343130323530313030383439393035373134303032303030303030303030303030303030313031 ,
经过ANSI-X9.9-MAC计算出MAC=7869E65451C9A183。