ARQC计算方法
2016-11-14 14:16
253 查看
import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESedeKeySpec; public class TripleDES{ public static void main(String[] args) throws Exception { //3DES密钥的长度必须是8的倍数,可取24位或32位; // 加密结果的byte数组转换为字符串,一般采用两种方式:Base64处理或十六进制处理。 String newkey1 = ""; String key = "C4D689158AD9FB9D23105B91CE046D0E"; String newkey = key.substring(0, 16); newkey1 = key + newkey; byte[] deskey8 = decode(newkey1); byte[] sourData = decode("2011000270735501DFEEFFFD8F8CAAFE"); String msg = encryptDesSede(deskey8, sourData); System.out.println(msg); } public static String encryptDesSede(byte[] hexKey, byte[] hexData) throws Exception{ final DESedeKeySpec dks = new DESedeKeySpec(hexKey); final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede"); final SecretKey securekey = keyFactory.generateSecret(dks); Cipher cp = Cipher.getInstance("DESede/ECB/NoPadding"); cp.init(Cipher.ENCRYPT_MODE, securekey); byte[] bytes = cp.doFinal(hexData); return HexBinary.encode(bytes); } public static byte[] decode(String pValue){ if ((pValue.length() % 2) != 0){ throw new IllegalArgumentException("A HexBinary string must have even length."); } byte[] result = new byte[pValue.length() / 2]; int j = 0; for (int i = 0; i < pValue.length();){ byte b; char c = pValue.charAt(i++); char d = pValue.charAt(i++); if (c >= '0' && c <= '9'){ b = (byte) ((c - '0') << 4); } else if (c >= 'A' && c <= 'F'){ b = (byte) ((c - 'A' + 10) << 4); } else if (c >= 'a' && c <= 'f'){ b = (byte) ((c - 'a' + 10) << 4); } else{ throw new IllegalArgumentException("Invalid hex digit: " + c); } if (d >= '0' && d <= '9'){ b += (byte) (d - '0'); } else if (d >= 'A' && d <= 'F'){ b += (byte) (d - 'A' + 10); } else if (d >= 'a' && d <= 'f'){ b += (byte) (d - 'a' + 10); } else{ throw new IllegalArgumentException("Invalid hex digit: " + d); } result[j++] = b; } return result; } public static String encode(byte[] pHexBinary){ StringBuffer result = new StringBuffer(); for (int i = 0; i < pHexBinary.length; i++){ byte b = pHexBinary[i]; byte c = (byte) ((b & 0xf0) >> 4); if (c <= 9){ result.append((char) ('0' + c)); } else{ result.append((char) ('A' + c - 10)); } c = (byte) (b & 0x0f); if (c <= 9){ result.append((char) ('0' + c)); } else{ result.append((char) ('A' + c - 10)); } } return result.toString(); } }
[摘要:ARQC:authenticate request cryptogram,受权要求报文 ARPC:authenticate response cryptogram,受权相应报文 AC:application cryptogram,运用稀文 AAC:application authenticate cryptogram,运用认证稀文 TC:transaction certificate,交]
ARQC:authenticate request cryptogram,授权请求报文
ARPC:authenticate response cryptogram,授权响应报文
AC:application cryptogram,应用密文
AAC:application authenticate cryptogram,应用认证密文
TC:transaction certificate,交易证书
ATC:application transaction counter,应用交易计数器
ARC:authenticate response code,授权应答码
前提:
1. 获得IC卡AC子密钥(应用子密钥),或者获得发卡行AC主密钥(应用主密钥) 本例假设卡片的应用主密钥为MDKAC,十六字节:
MDKAC = C4D689158AD9FB9D23105B91CE046D0E
2. 已知IC卡卡号PAN(5A)及卡序列号(5F34)
本例: PAN = 6210220110002707355 卡号一般为19位,最后一位是校验位, PAN ser = 01 ,卡序列号一般是一个字节,存储在tag5F34中
二、TC、ARQC及AAC的计算
a.首先需要取IC卡AC子密钥(应用子密钥),如果已经获得了IC卡AC子密钥(应用子密钥)则略过此步。
获取应用子密钥的方法: 用发卡行的应用主密钥===》分散===》IC卡的应用子密钥
用发卡行主密钥分散出IC卡AC子密钥。方法为使用发卡行主密钥,对PAN(卡号)的后14位(如果PAN不足14位前面补0)加PAN序列号(卡序列号,tag5F34)(共8B)和对此取反的8个字节连接得到的16字节数据,做3DES加密(上面为代码)计算就得到IC卡AC子密钥(应用子密钥)。
如: 用MDKAC=C4D689158AD9FB9D23105B91CE046D0E PAN = 62102 20110002707355 ,PAN ser = 01
对20110002707355 01 DFEEFFFD8F8CAAFE 做3DES加密得 B8A15DA5F7043C317D9FD8F8DFE2BD75(UDK)应用子密钥
(2011000270735501) =》取反 =》( DFEEFFFD8F8CAAFE)
(这就是所谓的有应用主密钥分散得到应用子密钥的过程)
b.计算得到过程密钥:
用IC卡AC子密钥(应用子密钥),对交易计数器ATC做3DES加密:
1.在ATC前补6字节0x00,对ATC取反,并在前补6字节0x00,并连接成16字节的数据,作为3DES的加密数据
例 如:ATC = 03D3 则 链接后的数据为: 00000000000003D3 000000000000FC2C (其中FC2C为03D3取反后的值,可以用计算器(程序员模式)验证)
2. 用IC卡的AC子密钥(应用子密钥)对如上数据做3DES加密得过程密钥:
如: 用UDK对00000000000003D3000000000000FC2C做3DES加密得到的结果即是:4A43440B2D932ACDC4E2776ED562EE43 (过程密钥 )
3.校验AAC、TC及ARQC
IC卡返回的55域数据为: 待校验的密文: 81 A9 DC 93 10 F8 88 56
授权金额: 000000000000 9F0206
其它金额: 000000000000 9F0306
国家代码: 0156 9F1A02
终端验证: 0000000000 9505
货币代码: 0156 5F2A0
交易日期: 000000 9A03
交易类型: 00 9C01
随机数: 00000444 9F3704
AIP: 7C00 8202
ATC: 03D3 9F3602
CVR: 0380A800 9F1013
连接如上数据得:
000000000000 000000000000 0156 0000000000 0156 00000000 00000444 7C00 03D3 0380A800
用过程密钥对如上数据做MAC运算得到了AAC(应用认证密文)、TC(交易证书)或ARQC(授权响应报文):
AAC、TC或ARQC = 81A9DC9310F88856 与IC卡返回的响应密文比较相等,校验成功!
三、ARPC的计算方式
a.取授权应答码(ARC)
授权应答码为服务器返回的两字节数据,本例假设为:“00” 则ARC = 0x30 0x30 (十六进制)
ARPC计算过程
1. 在ARC后补6个字节0x00,并和ARQC做异或运算 如: 3030 000000000000 异或(XOR) 81A9DC9310F88856 得 B199DC9310F88856
2. 使用过程密钥对异或结果做3DES加密运算就得到ARPC
过程密钥:4A43440B2D932ACDC4E2776ED562EE43 对B199DC9310F88856 做3DES加密运算得ARPC密文:84DD63A221F915CA(ARPC)
3. 命令(外部认证) 00 82 00 00 0A +ARPC(8B)+ARC(2B)
相关文章推荐
- 金融IC卡 ARQC和ARPC计算方法和实例
- 金融IC卡 ARQC和ARPC计算方法和实例(转)
- 总线带宽的计算方法
- 在php和MySql中计算时间差的方法详解
- 18位身份证号码最后一位校验码的计算方法
- 恒星时的计算方法
- 宽带速度的计算方法
- 三维模型顶点法向量和偏导数的计算方法
- 【农历】计算方法
- SQL计算秒数的一个简单方法
- 星表计算方法的说明
- 在php和MySql中计算时间差的方法
- 【农历】计算方法--- (阳历转阴历)
- 实现文本自动分类的基础----Term频率计算方法
- Oracle数据库中日期的计算方法
- 双精度浮点数的加法计算误差及其避免的初步方法
- php中计算时间差的几种方法
- asp.net中计算两个日期之间的相差的天数的方法(vb)
- 折线平行线的计算方法
- 实现文本自动分类的基础----Term频率计算方法