http://m.blog.csdn.net/xinxinsky/article/details/52315592 PIN
二进制文件:数据以字节为单位进行读写,每次读写的长度不能超过110字节;可用于存储无序的数据。
http://blog.tianya.cn/blogger/post_show.asp?BlogID=103231&PostID=10565372 密钥认证
http://www.doc88.com/p-7415947255776.html发卡http://blog.csdn.net/lupengfei1009/article/details/53002341?fps=1&locationNum=6 cpu擦出
http://www.doc88.com/p-435424638247.html
http://blog.csdn.net/redumbrella/article/details/7569885
http://m.blog.csdn.net/xinxinsky/article/details/52315592 cpu发卡步骤
http://blog.csdn.net/xinxinsky/article/details/52288859 外部认证
http://blog.csdn.net/redumbrella/article/details/7571186 专业文件
---------------------
*******************************************
函数名称:EsamInsideVali
函数功能:ESAM过程密钥内部认证
输入参数: pcReceCardRand-卡产生的随机数,KEYNum1,内部认证密钥标识
输出参数:无
描述:发命令头--发数据-发取响应数据命令--获得数据
*******************************************/
unsigned char* EsamInsideVerify(unsigned char* pcReceCardRand,unsigned char KEYNum1)
{
unsigned char cReceCardDatdBuff2[8]={0};
unsigned char *pcReceDataBuff;
unsigned int itemp;
cCommandLen=0x05;
TxAndRxBuff[0]=0x80;
TxAndRxBuff[1]=0xfa;
TxAndRxBuff[2]=0x00;
TxAndRxBuff[3]=KEYNum1;
TxAndRxBuff[4]=0x08;
SendCommandHead_Pro(); //发命令头
if(ErrorReadWriteBIT&iErrorRWrCard) goto EsamInsideValiEnd;
memcpy(&TxAndRxBuff[0],pcReceCardRand,8);
Delay1XETU(4);
cCommandLen=8;
SendCommand(cCommandLen);//发数据
TxAndRxBuff[0]=EsamReceChar();
TxAndRxBuff[1]=EsamReceChar();
SendC0Comm(); //发“取响应数据”命令
for(itemp=0;itemp<8;itemp++)
{
cReceCardDatdBuff2[itemp]=EsamReceChar(); //接受ESAM返回信息
if(ErrorReadWriteBIT&iErrorRWrCard) break;
}
TxAndRxBuff[0]=EsamReceChar();
TxAndRxBuff[1]=EsamReceChar();
if((TxAndRxBuff[0]!=0x90)&&(TxAndRxBuff[1]!=0x00))
{
iErrorRWrCard=ErrorReadWriteBIT|iErrorRWrCard;
goto EsamInsideValiEnd;
}
EsamInsideValiEnd:
pcReceDataBuff=&cReceCardDatdBuff2[0];
delay_ms2M(5);
return pcReceDataBuff;
}
---------------------
基于PBOC的电子钱包消费交易过程
首先终端和卡片有一个共同的密钥叫做消费密钥:PurchKey
假设PurchKey = 11223344556677888877665544332211 在满足安全条件的情况下:
第一步:终端向卡片发送消费初始化命令:
Apdu: 80 50 01 02 0B 01 00001000 001122334455
CLA INS P1 P2 LC KeyIndex 交易金额 终端机编号
P1:密钥用途、P2:密钥版本、 Lc:密钥文件信息长度、KeyIndex:密钥文件标识符
卡片返回15个字节的数据如下(不包括9000):
00000000 0000 000000 01 00 11223344
卡片余额 交易序号 透支限额 密钥版本号 算法标识 随机数
MAC1的计算过程如下(终端):
1.计算过程密钥:SessionKey
InputData = 11223344 0000 0001 (8bytes)
随机数 卡片脱机交易序号 终端交易序号后四位
PurchKey = 11223344556677888877665544332211(消费密钥)
SessionKey = 3DESEnypt(InputData, PurchKey) =003238ABC57659DD(计算过程密钥)
用LoadKey输入键对InputData输入数据 做3DES加密
2.计算MAC1
InputData1 = 00001000 06 001122334455 20120229135100
交易金额 交易类型 终端机编号 日期时间
SessionKey = 003238ABC57659DD
MAC1 = MAC(InputData1SessionKey ) = F15CAB75
用SessionKey对InputData1做MAC运算
第二步:终端向卡片发送消费命令:
Apdu: 80 54 01 00 0F 00000001 20111221214822 3A845BF0
CLA INS P1 P2 LC 终端交易序号 交易日期时间 MAC1
卡片用同样的方法计算MAC1并验证终端发来的MAC1是否正确来确认终端是否合法。如果MAC1验证没通过,卡片会返回MAC错误终止交易。如果MAC1验证通过,进行第三步。
第三步:卡片修改余额,脱机交易序号加1并计算MAC2 和TAC,并返回给终端
3.计算MAC2
InputData2= 00001000 交易金额
SessionKey = 003238ABC57659DD
MAC2 = MAC(InputData2 SessionKey ) = 56988A13
用SessionKey对InputData2做MAC运算,
4.计算TAC
卡片和终端还有一个共同的密钥TAC密钥:TACKey
假设TACKey = 00112233445566778899AABBCCDDEEFF
TACSessionKey=XOR( Left(8),Right(8)) =8888888888888888
TACKey左右8个字节做异或运算
InputData3=00001000 01 001122334455 00000001 20111221 214822
交易金额 交易类型 终端机编号 终端交易序号 交易日期 交易时间
TAC = MAC(InputData3, TACSessionKey) = 3FF7A28A
MAC2和TAC作为消费命令的返回数据返回给终端,消费交易到此就结束了,TAC作为清算的时候验证交易数据真伪和完整性的重要依据,连同交易记录一同保存在终端。
TAC的计算方法:
初始向量: 00 00 00 00 00 00 00 00
待处理数据:4字节交易金额 +1字节交易类型标识+6字节终端机编号+4字节终端交易序号+4字节终端交易日期+3字节终端交易时间
密钥:TAC密钥左8字节与右8字节异或得到的8字节数据
算法:DES_MAC 算法
说明:以下计算TAC的流程适用于:
1.如果PSAM卡中TAC秘钥类型是口令重装密钥类型,则此PSAM卡中的TAC密钥对CPU卡中的分散因子分散之后=CPU卡中的TAC密钥,因为 口令重装密钥在被使用时COS会自动左右8字节进行异或。
2.如果PSAM卡中的TAC密钥类型是加密MAC密钥,或者是MAC密钥类型,则此PSAM卡TAC密钥对CPU卡中的分散因子分散之后=CPU卡中的TAC密钥左右8字节异或的值
---------------------
电子钱包CPU卡和PSAM卡消费密钥装载分析
1.PSAM卡中一个ADF下消费密钥区分
装载不同的消费密钥根据密钥版本号来区分,CPU卡中消费密钥密钥版本要和PSAM卡中密钥版本相同
还有算法标识
00-3DES
01-DES
02-255保留
注意:消费密钥的密钥版本是在消费过程中标识密钥版本,其他的密钥的密钥版本作为密钥标识使用。
2.PSAM卡中密钥用途设置
高3位是分散密级,低5位是密钥类型
一级分散是0x01<<5 =0x20 消费密钥是0x02 ,所以密钥用途应该是
0x20|0x02 = 0x22
二级分散消费密钥的密钥用途应该是 0x40|0x02 = 0x42
三级分散消费密钥的密钥用途应该是0x60|0x20 = 0x62
注意:1.消费时PSAM卡中至少要进行一次密钥分散,我一直想一次不分散没成功…..
2.消费密钥的密级应该和获取MAC1命令中的LC相对应:
密级=1, Lc=0x14 + 1*8
密级=2, Lc=0x14 + 2*8
密级=3, Lc=0x14 + 3*8
当然获取MAC1命令中数据域也要按顺序加入相应的分散因子
3.PSAM卡中的消费密钥装载
PSAM卡中的消费密钥装载时应该用当前应用下的主控密钥对消费密钥进行加密和计算MAC
Eg:
84 D4 0000 1C
CLA INS P1 P2 Lc
Lc后面的数据全部进行DES加密,然后把加密数据和命令拼接
把拼接好的命令进行MAC计算,其中Lc长度为加密之后的数据长度+4
DATA域数据:22 00 0000112233445566778899aabbccddeeff
用3DES对DATA加密,在加密之前先稍微对其进行处理,添加明文长度,分块不足8字节补80 00 …
命令线路加密保护计算:
3DES-ECB模式
处理数据:
13 22 0000 00112233445566778899aabbccddeeff 80 00 00 00
0x13 是62-FF的明文要加密的数据长度 19个
80 00 00 00 是对要加密数据的补充,因为分块之后不足8字节
22 是密钥用途,6是分散级数,2是密钥类型-消费
00 00 是密钥版本和算法标识
00112233445566778899aabbccddeeff 要添加的密钥明文
密钥:00112233445566778899aabbccddeeff (当前应用下的主控密钥)
结果:DCC0BB5793ABFCA2CA8C1624822F6E01A86A0B5CBED191DD(数据域加密之后的数据)
MAC-CBC模式-DES
初始向量:5d 72 b3 fd 000000000 (5d 72 b3 fd从卡片获取的4字节随机数)
处理数据:84D400001CDCC0BB5793ABFCA2CA8C1624822F6E01A86A0B5CBED191DD
密钥:00112233445566778899aabbccddeeff (当前应用下的主控密钥)
结果:8A9D4ADB
完整命令
84D400001CDCC0BB5793ABFCA2CA8C1624822F6E01A86A0B5CBED191DD8A9D4ADB
4.CPU卡中的密钥
此时CPU卡中的密钥应该是分散之后的密钥
密钥分散算法:
注意:PSAM卡中装载的密钥对分散因子进行一级一级分散,具体分散几次根据PSAM卡中密钥装载时的分散级数确定
1.密钥(PSAM卡中装载的密钥或者是上次分散之后的密钥)对8字节分散因子做3DES加密得到的8字节作为新分散密钥的左8字节
2. 密钥(PSAM卡中装载的密钥或者是上次分散之后的密钥)对8字节分散因子取反之后的数据 做3DES加密得到的8字节作为新分散密钥的右8字节
3.把上面两步骤获取的左右各8字节拼接起来就是新的16字节分散密钥
4.如果还有下一级分散,把新获取的分散密钥作为对分散因子加密的密钥
重复上述三个步骤。
Eg:
目的:将PSAM卡中装载消费密钥,消费时对用户卡序列号进行一级分散
能够与装载相应密钥的CPU卡进行消费
PSAM卡中消费密钥是:00112233445566778899aabbccddeeff
分散因子:8字节卡应用序列号 122334455667788
DPK左半部分
卡应用序列号:1122334455667788
密钥:00112233445566778899aabbccddeeff
结果:496BD7A351364453
DPK右半部分
卡应用序列号求反:eeddccbbaa998877
密钥:00112233445566778899aabbccddeeff
结果:3100B54E71196528
最终结果:496BD7A3513644533100B54E71196528
装载命令:80D40000153EF0F20000496BD7A3513644533100B54E71196528
注意:密钥装载之前是否做其他验证看密钥文件建立时的增加权限
此时
PSAM卡中消费密钥是:00112233445566778899aabbccddeeff
CPU卡中消费密钥是:496BD7A3513644533100B54E71196528
---------------------
电子钱包交易过程中利用PSAM卡计算 TAC--交易验证码
---
目的:自己计算TAC并且和CPU卡消费成功后产生的TAC值相同
原因:电子钱包交易过程中可能会出现闪卡现象(用户卡中的金额已经扣除,但是终端没有收到卡片返回的TAC和MAC2),所以再次靠卡时,终端会判断是否是闪卡,如果是则终端根据之前的交易数据,自行计算TAC,然后上送后台系统。
TAC的计算方法:
初始向量: 00 00 00 00 00 00 00 00
待处理数据:4字节交易金额 +1字节交易类型标识+6字节终端机编号+4字节终端交易序号+4字节终端交易日期+3字节终端交易时间
密钥:TAC密钥左8字节与右8字节异或得到的8字节数据
算法:DES_MAC 算法
说明:
以上过程全部CPU卡,PSAM内部COS自动完成。
以下计算TAC的流程适用于:
1.如果PSAM卡中TAC秘钥类型是口令重装密钥类型,则此PSAM卡中的TAC密钥对CPU卡中的分散因子分散之后=CPU卡中的TAC密钥,因为 口令重装密钥在被使用时COS会自动左右8字节进行异或。
2.如果PSAM卡中的TAC密钥类型是加密MAC密钥,或者是MAC密钥类型,则此PSAM卡TAC密钥对CPU卡中的分散因子分散之后=CPU卡中的TAC密钥左右8字节异或的值
例程计算:
先用CPU卡消费计算一个TAC,并且保存计算TAC需要的数据,
然后用相关数据自己计算TAC,比较和CPU卡产生的TAC是否相同,
计算过程中使用PSAM卡的DES初始化命令进行分散密钥,DES命令计算TAC。
CPU卡消费过过程中的相关数据:
CPU卡机构代码: 07 92 80 00 00 00 01 45
用户卡序列号: 20 16 12 21 00 00 10 03
日期时间: 0170214154000
终端交易序号 : 00000005
交易金额: 00000001
终端机编号: 36 04 86 60 00 02
交易类型标识: 09
CPU卡消费成功返回的TAC+MAC2
a5 71 7b 4f 99 09 f5 38
使用PSAM卡计算TAC:
1.发送DES初始化命令分散TAC密钥:
80 1A 44 00 10 20 16 12 21 00 00 10 03 07 92 80 00 00 00 01 45
长度
值
描述
代码
(byte)
(Hex)
CLA
1
80
INS
1
1A
P1
1
44
密钥用途,TAC密钥
P2
1
00
密钥版本,TAC密钥标识
Lc
1
10
分散因子的长度16字节
DATA
XX
20 16 12 21 00 00 10 03
07 92 80 00 00 00 01 45
分散因子:
卡序列号
机构代码
Le
—
不存在
<=90 00
2.发送DES命令计算TAC
待处理数据:
00000001 09 36 04 86 60 00 02 00000005 20170214154000
4字节交易金额 +1字节交易类型标识+6字节终端机编号+4字节终端交易序号+4字节终端交易日期+3字节终端交易时间
因为数据不是8的倍数,所以要分块补足:
00000001 09 36 04 86 60 00 02 00000005 20170214154000 80 00
(补80 00凑够16字节)
DES命令:
80 FA 05 00 20 00 00 00 00 00 00 00 00 00000001 09 36 04 86 60 00 02 00000005 20170214154000 80 00
长度
值
描述
代码
(byte)
(Hex)
CLA
1
80
INS
1
FA
P1
1
05
采用MAC计算方式,有初始值,无后续块
P2
1
00
DES标识号
Lc
1
20
要计算的数据长度
DATA
XX
00 00 00 00 00 00 00 00
00000001 09 36 04 86
60 00 02 00000005
20170214154000 80 00
16字节的计算+
TAC所需数据8字节初始值
Le
—
不存在
采用MAC计算方式,有初始值,无后续块
<=a5 71 7b 4f 90 00
CPU卡返回的TAC:a5 71 7b 4f
结论:利用PSAM卡自己计算TAC是可行的,方法如上
---------------------
原文:https://blog.csdn.net/u011548018/article/details/73381283