1.磁条卡原始数据
MPOS需要保证从磁条卡满足《GBT_19584-2010_银行卡磁条信息格式和使用规范》中规定的数据格式。以二磁道为例,设备读取的磁道数据为:
;6227003390501149081=50125204813420000?
2.加密算法
磁条信息加密采用标准的DESede,双倍长密钥,ECB,NoPadding模式进行加解密。用于磁条信息加密的双倍长密钥在MPOS进行设备签到时进行获取。在进行加密前,需要将磁道数据变换为标准的ASCII码字节流,如果字节流长度不是8的整数倍,在字节流后先补一个字节0x80,然后继续补0x00直到字节流的长度为8的整数倍,最后将补位的数据进行3DES加密。
3.加解密的java实现:
package com.qdone;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.ArrayUtils;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class Main {
public static void main(String[] args) throws Exception {
// 磁道2数据
String track2=";6227003390501149081=50125204813420000?";
System.out.println("磁道原始数据:"+track2);
byte[] track2Bytes=track2.getBytes("ASCII");
// 补字节80
track2Bytes=ArrayUtils.add(track2Bytes,(byte)0x80);
//判断补多少字节是8的整数倍
int pad=8-track2Bytes.length % 8;
// 用字节0补全
for(int i=0;i<pad;i++) {
track2Bytes=ArrayUtils.add(track2Bytes,(byte)0x00);
}
String track2BytesHex=Hex.encodeHexString(track2Bytes);
System.out.println("处理后的数据:"+track2BytesHex);
// 磁道密钥,双倍长,32位,16字节
String key="12345678ABCDEF00ABCDEF0012345678";
// 将密钥变为三倍长,48位,24字节
key=key+ key.substring(0, 16);
byte[] keyBytes=Hex.decodeHex(key.toCharArray());
// 构造密钥
SecretKey keySpec = new SecretKeySpec(keyBytes, "DESede");
// 生成加密算法
Cipher cipher=Cipher.getInstance("DESede/ECB/NoPadding");
// 初始化为加密模式
cipher.init(Cipher.ENCRYPT_MODE,keySpec);
// 加密
byte[] encData=cipher.doFinal(track2Bytes);
String encHex=Hex.encodeHexString(encData);
System.out.println("磁道加密数据:"+encHex);
// 解密
cipher.init(Cipher.DECRYPT_MODE,keySpec);
byte[] decData=cipher.doFinal(encData);
String decHex=Hex.encodeHexString(decData);
System.out.println("磁道解密数据:"+decHex);
// 找到最后出现的80
int idx=ArrayUtils.lastIndexOf(decData,(byte)0x80);
// 去掉补位数据
decData=ArrayUtils.subarray(decData,0,idx);
// 字节流转字符串
String track2Data=new String(decData,"ASCII");
System.out.println("磁道原始数据:"+track2Data);
}
}
运行后的输出:
磁道原始数据:;6227003390501149081=50125204813420000?
处理后的数据:3b363232373030333339303530313134393038313d35303132353230343831333432303030303f800000000000000000
磁道加密数据:9b9346badaab1ba09fb5174b1e49c1d669876fb57bc3731828997b61ca97050de00d35dee3ce79b8f48ab9725bb20af1
磁道解密数据:3b363232373030333339303530313134393038313d35303132353230343831333432303030303f800000000000000000
磁道原始数据:;6227003390501149081=50125204813420000?