cpu卡圈存交易流程
利用发卡器,psam卡,cpu卡进行圈存指令。
主要流程如下:
1.获取psam卡终端编号
2.读取MF公共信息文件,获取cpu卡[卡应用序列号]和[发卡机构代码]
3.选择应用,验证口令
4.圈存初始化
5.利用psam卡加密通用初始化
6.利用psam卡计算过程密钥
7.利用过程密钥计算MAC1,和初始化得到MAC1进行比对
8.比对一致,进行MAC2计算
9.发cpu卡发送圈存指令
10.拿到cpu返回的TAC进行验证
获取psam卡终端编号,cpu卡应用序列号,发卡机构代码
前提:psam卡和cpu卡已建立卡结构,并已完成写卡操作。 需要了解APDU指令的基本知识。
获取psam卡终端编号
命令:
00B0960006
命令解析:
00 B0 读二进制文件指令
96 00 代表文件标识是0016,那这里的96如何解释呢?按如下描述,P1的高三位需要变成100。 另外这里的00是代表偏移量是0若 P1 的高三位为 100,则低 5 位为短的文件标识符,P2 为读的偏移量。若 P1的最高位不为 1,则P1 P2
为欲读文件的偏移量(P1 为偏移量高字节,P2 为低字节),所读的文件为当前文件。 若 P1的最高位不为 1,则P1 P2
为欲读文件的偏移量(P1 为偏移量高字节,P2 为低字节),所读的文件为当前文件。最后的06是返回数据的长度。
按照卡的结构定义,文件标识0016的文件前6个字节就是终端编号,
所以返回值就是终端编号。
终端编号:000142300727
cpu卡应用序列号,发卡机构代码
命令:
00B083006D
命令解析:
83 00 代表文件标识是0003
返回值:
0013401000140002B2340101000004FFFF3401FFFFFFFFFFFF0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000
返回值解析:
按照卡结构定义
文件标识0003是公共信息文件,按卡结构定义,顺序存储
2字节的卡种类型,8字节卡应用序列号,8字节机构代码,8字节城市代码。所以按照这个顺序去解析返回值得到。
应用序列号:13401000140002B2
发卡机构代码:340101000004FFFF
验证口令
前提:需要先选择应用,这里选择DF01
这里解释一下为什么要验证口令。因为后续操作比如圈存初始化需要验证口令之后才有权限。
命令:
00A4000002DF01
命令:
0020000003000000
命令解析
0020 验证口令指令
0000 P1固定是00,> P2 口令密钥标识符(支持多个PIN)00
03 Lc 口令长度
000000口令,cpu卡写卡时录入的口令。
圈存初始化
初始化圈存交易
指令说明:
80 50 00 02(电子钱包) 0B(Lc) 00(密钥标识符) 00 00 27 10 (交易金额)00 01 42 30 07 27(终端编号)
返回说明:
00 00 26 48(电子钱包余额) 00 01(电子钱包联机交易序号) 01 (密钥版本号)01(算法标识) C4 8D 33 06 (伪随机数)82 BE F5 28(MAC1) 9000(成功状态码)
算法标识 01 表示DES算法,00表示3DES算法
这里的
MAC1 由卡中过程密钥对(4 字节电子存折或电子钱包旧余额+4 字节交易金额+1 字节交易类型标识+6 字节终端机编号) 数据加密生成。
而过程密钥由 DATA 中第一字节即密钥标识符指定的圈存密钥对(4 字节随机数+2 字节电子存折或电子钱包联机交易序号+8000)数据加密生成
过程密钥获取
前提:选择了psam卡的DF01应用
第一步需要对psam卡进行通用加密计算初始化,即INIT FOR ENCRYPT
INIT FOR ENCRYPT 命令将指定的 KEY 分散至临时密钥寄存器中。该命令只支持分散 KEY,不产生过程 KEY。分散后的子 KEY 继承原始 KEY 的属性。
INIT FOR ENCRYPT 命令的执行应满足 KEY 的使用权
简单来说就是对密钥进行分散,得到临时密钥。
这里我理解为是对加密密钥进行分散,得到圈存密钥。
指令说明:
801A 47(密钥用途)01(密钥版本)10(Lc)13401000140002B2340101000004FFFF(卡应用序列号 + 发卡机构代码)
P1 为密钥用途(高3位为分散级数,低 5 位为密钥类型),P2 为密钥版本。算法标识由密钥属性决定。
47 2进制为01000111,分散级数是2,密钥类型为7。
根据卡结构文档,47是圈存密钥,48是写文件计算MAC用的密钥。
第二步进行通用加密计算 ,即DES ENCRYPT
对输入数据进行安全计算,支持的安全计算包括: 3DES ,3DES 计算 MAC、SM4 加解密,SM4计算MAC (取决于PSAM卡型号,不同型号支持的算法都不一样)
MACDES ENCRYPT 命令的执行应以 INIT FOR ENCRYPT 命令为前提条件,即该命令的上一条命令应是INIT FORENCRYPT。该命令所使用的 KEY,固定为临时密钥寄存器中的 KEY
本命令成功执行后临时密钥寄存器中的 KEY 即刻失效。
简单来说就是利用上一步产生的临时密钥,对输入数据进行加密返回。
这里我理解为使用圈存密钥对(4字节随机数+2字节电子钱包联机交易序号+8000)数据加密生成过程密钥。
指令说明:
80 FA 00(P1) 00 08(Lc) C4 8D 33 06(随机数) 00 01(电子钱包联机交易序号) 8000(固定参数)
P1 参数说明:
00 无后续块加密
3DES算法。Lc应是8的模且大于0,SM4算法,是16的模且大于0
DES,3DES算法加密,加密数据长度是8的整数倍。SM4要求是16的整数倍。
P1为00时,返回值为加密结果,这里是称为过程密钥。
MAC1和MAC2计算
MAC1的计算
将上一步得到的过程密钥,按照圈存初始化提到的过程,对(4 字节电子存折或电子钱包旧余额+4 字节交易金额+1 字节交易类型标识+6 字节终端机编号) 数据进行加密,得到MAC1,加密算法根据圈存初始化的返回值算法标识01,采用DES算法。
8字节的初始值是16个0。
加密数据为16字节,如果不足,最后一位加上80
例如
00004D58000027100200014230072780
00004D58(旧余额)00002710(交易金额)02(交易类型标识)000142300727(终端机编号)80
生成的MAC1和圈存初始化得到的MAC1进行比对,如果一致,才会继续。否则圈存失败。
圈存失败的原因是MAC2也会计算的不对,导致CPU圈存指令失败。
不一致的原因,除了参数弄错了,大概率是因为psam卡的中密钥和cpu卡的中密钥不匹配。
MAC2的计算
MAC2 由卡中过程密钥对(4 字节交易金额+1 字节交易类型标识+6 字节终端机编号+4字节主机交易日期+3 字节主机交易时间) 数据加密生成。
加密数据为24字节,不足的补上80和00,例如
00002710(交易金额)02(交易类型标识)000142300727(终端机编号)20231110(交易日期)162442(交易时间) 80 00 00 00 00 00
发cpu卡发送圈存指令
圈存交易指令
指令解析:
805200000B(Lc)20231110162442(交易时间)22392DF0(MAC2)
返回值 4字节交易验证码TAC
TAC 用内部密钥 DTK 左右 8 位字节异或运算的结果对(4 字节电子存折或电子钱包新余额+2 字节电子存折或电子钱包联机交易序号(加 1前) +4 字节交易金额+1 字节交易类型标识+6 字节终端机编号+4 字节主机交易日期+3 字节主机交易时间) 数据加密生成。
TAC验证
TODO
实例测试
00B0960006
<<0001423007279000
00A4000002DF01
<<6F16840E4554532E65436172642E44463031A5049F0801029000
00B083006D
<<0013401000140002B2340101000004FFFF3401FFFFFFFFFFFF0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000
00A4000002DF01
<<6F16840E4554532E65436172642E44463031A5049F0801029000
0020000003000000
<<9000
805000020B0000002710000142300727
<<0000746800030101B8BDBB44019BC6669000
801A47011013401000140002B2340101000004FFFF
<<9000
80FA000008B8BDBB4400038000
<<66DF419B70E1A4D19000
805200000B20231110164716834F8F1F
<<E7018D969000