Android的isoDep.transceive上产生AC命令总是返回6D00不受支持 [英] Android isoDep.transceive on Generate AC command always returns 6D00 unsupported

查看:1562
本文介绍了Android的isoDep.transceive上产生AC命令总是返回6D00不受支持的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图模仿POS,销售点:),系统和完成交易与2013年的Nexus 7(无安全元件)v4.4.2运行谷歌钱包。

我的销售点的原型也是在2013年的Nexus 7 v4.4.2运行。

我能够得到从2PAY_SYS_DDF01要求NFC响应。 我可以选择万事达应用程序ID。 我能够得到处理选项。 当我读到记录它看起来并不像谷歌钱包返回所有强制EMV领域。 最后,当我请求生成AC命令时,它总是返回6D00不支持的。

的code这是一个问题领域:

  //设置P1为'40',索要交易凭证(脱机事务)
//并执行生成AC命令。

byte []的generateAC =新的字节[] {(字节)0x80的,(字节)0xAE,0X40,0×00,
                0x1D,//数据长度
                0×00,0×00,0×00,0×00,0×00,0×01,// amount1
                0×00,0×00,0×00,0×00,0×00,0×00,// amount2
                0×08,0X40,//长期国
                0×00,0×00,0×00,0×00,0×00,// TVR
                ×09,0X62,// TX CURR
                0×14,0×04,0x1B,// TX日期
                0×00,// TX型
                0×12,0x34,0x56,0x78,//随机
                0×00}; //乐
响应= isoDep.transceive(generateAC);
 

我是继蒂姆·贝格尔视频 https://www.youtube.com/watch?v=qqobg1-HrfY 约。 46分钟研究。 和蒂姆·贝克斯code样品: https://github.com/a2800276/29c3/blob/master/smartshell.rb

更新:

要在GPO命令的响应( 80 A8 00 00 02 83 00 00 )的

  770a820200009404080101009000

77响应消息的模板格式2
    82应用交互特征
        0000
    94应用文件定位器(AFL)
        08010100
 

更新:

我想:

 字节[] computeCC =新的字节[] {
(字节)0x80的,// CLA =专利
(字节)0x2A,// INS = COMPUTE加密校验
(字节)为0x8E,// P1
(字节)0x80的,// P2
(字节)0×04,// LC
(字节)为0x00,0x00时,(字节)为0x00,(字节)0x99,//联合国predicatable号(数字)
(字节)为0x00,//乐
};
响应= isoDep.transceive(computeCC);
 

希望至少拿到指示的错误未predictable一些错误,但我得到了6700长度不正确返回。

早些时候,我得到了响应读取记录00 B2 01 0C 00 这种反应的一部分是     卡身份验证相关数据[9F69]:     数据(二进制):XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX     FDDA版本号:9F     (卡)联合国predictable编号:6A 04 9F 7E

所以,我想,联合国predictable号

 字节[] computeCC =新的字节[] {
(字节)0x80的,// CLA =专利
(字节)0x2A,// INS = COMPUTE加密校验
(字节)为0x8E,// P1
(字节)0x80的,// P2
(字节)0×04,// LC
(字节)的0x6A,0x04的(字节)0x9F,(字节)的0x7E,//联合国predicatable号(数字)
(字节)为0x00,//乐
};
响应= isoDep.transceive(computeCC);
 

不过,我仍然得到6700错误的长度

更新:

响应读记录(记录= 1,SFI = 1)命令(00 B2 01 0C 00) 是:

  70 7C 9F 6C 02
00 01 9F 62 06
00 00 00 00 00
38 9F 63 06 00
00 00 00 03 6
56 29 42 35 33
39 36 XX XX XX
XX XX 31 XX 39
XX XX XX XX 5E
20 2F 5E 31 34
30 37 31 30 31
34 30 31 30 30
30 30 30 30 30
30 30 30 9F 64
01 04 9F 65 02
00 38 9F 66 02
03 C6 9F 6B 13
53 96 XX XX 1X
X9 XX XX D1 40
71 01 40 10 00
00 00 00 0F 9F
67 01 04 9F 69
0F 9F 6A 04 9F
7E 01 9F 02 06
5F 2A 02 9F 1A
02 90 00

-------------------------- TLV ----------------------- --------
输出:
读记录响应报文模板[70]:
    卡交易预选赛(CTQ)[9F6C]:
    数据(二进制):00 01
位标志设置:
    1Bxb8:0  - 在线密码不要求
    1Bxb7:0  - 签名不要求
    1Bxb6:0  - 不适用:去网上如果脱机数据认证失败和Reader是网上能。
    1Bxb5:0  - 不适用:如果脱机数据认证失败和读卡器支持VIS交换接口。
    1Bxb4:0  - 不适用:去网上,如果申请过期
    1Bxb3:0  - 不适用:交换机接口现金交易
    1Bxb2:0  - 不适用:对于现金返还事务交换接口
    1Bxb1:0  - 俄罗斯足协
    2Bxb8:0  - 消费者设备CVM不执行
    2Bxb7:0  - 卡不支持发卡行更新处理的POS
    2Bxb6:0  - 俄罗斯足协
    2Bxb5:0  - 俄罗斯足协
    2Bxb4:0  - 俄罗斯足协
    2Bxb3:0  - 俄罗斯足协
    2Bxb2:0  - 俄罗斯足协
    2Bxb1:1  - 俄罗斯足协
PCVC3(TRACK1)[9F62]:
    数据(二进制):00 00 00 00 00 38
离线计数器初始值[9F63]:
    数据(二进制):00 00 00 00 03 6
1轨数据[56]:

    数据(ASCII):B5396XXXXXXXXXXXX ^ / ^ 14071014010000000000
NATC(TRACK1)[9F64]:
    数据(二进制):04
PCVC3(TRACK2)[9F65]:
    数据(二进制):00 38
终端交易限定符(TTQ)[9F66]:
    数据(二进制):03 C6
卡CVM限制[9F6B]:
    数据(二进制):53 96 48 50 17 6​​9 62 32 D1 40 71 01 40 10 00 00 00 00 0F
MSD偏移[9F67]:
    数据(二进制):04
卡身份验证相关数据[9F69]:
    数据(二进制):9F 6A 04 9F 7E 01 9F 02 06 5F 2A 02 9F 1A 02
FDDA版本号:9F
(卡)联合国predictable编号:6A 04 9F 7E
卡交易预选赛:01 9F
----------------------------------------
 

解决方案

到GET处理选项命令的响应指示以下应用交互特征(AIP):

  82应用交互特征
    0000
 

谷歌钱包基本上是万事达卡(EMV非接触式内核2),根据内核的规则,因此解码AIP 2的结果如下:

 字节1,B7 = 0:不支持SDA
        B6 = 0:无DDA支持
        B5 = 0:不支持持卡人验证
        B4 = 0:无终端风险管理执行
        B3 = 0:不支持任何发卡行认证
        B2 = 0:无设备上的持卡人验证支持
        B1 = 0:无CDA支持
字节2,B8 = 0:不支持EMV模式
 

最重要的部分是字节2,位8:这表明你的显卡不支持EMV模式。因此,你的卡/谷歌钱包是只支持磁条模式的PayPass卡。因此,您可以使用GENERATE AC无法验证交易。相反,你可以只让卡生成动态卡片验证​​codeS(CVC3)使用电子计算机加密校验:

 字节[] computeCC =新的字节[] {
    (字节)0x80的,// CLA =专利
    (字节)0x2A,// INS = COMPUTE加密校验
    (字节)为0x8E,// P1
    (字节)0x80的,// P2
    (字节)0×04,// LC
    (字节)0xWW,(字节)0XXX,(字节)0xYY,(字节)0xZZ,//联合国predicatable号(数字)
    (字节)为0x00,//乐
};
响应= isoDep.transceive(computeCC);
 

需要注意的是电子计算机加密校验命令的数据字段必须填充根据UDOL值(如果没有UDOL,默认UDOL是 9F6A04 ,表明未predictable数,数字)。

的未predictable号(数字)是在由所述磁条数据文件中定义的范围内的BCD $ C $光盘号码(见AFL)。在过去,谷歌钱包,这是0到99之间的值(即 WW = '00' XX = '00' YY = '00' ZZ = '00'..'99')。

更新:

如下的卡去codeS读取的数据:

  70 7C
  9f6c 02磁条的应用程序版本号= 1版
    00 01
  9f62 06轨道1位映射CVC3
    00 00 00 00 00 38
  9f63 06轨道1位映射联合国和ATC
    00 00 00 00 03 6
  56 29 1轨数据
    42 ISO / IEC 7813结构B格式
    35333936 XXXXXXXX 31XXXX39 XXXXXXXX PAN(ASCII)
    5E字段分隔符^
    202F持卡人姓名/(空见MC要求)
    5E字段分隔符^
    31343037有效日期14/07
    313031服务code101
    34303130303030303030303030轨道1裁量数据
  9f64 01轨道1号的ATC位数
    04
  9f65 02音轨2位映射CVC3
    00 38
  9f66 02音轨2位地图为联合国和ATC
    03 C6
  9f6b 13磁道2数据
    5396 XXXX XXXX 1XX9 PAN(BCD)
    D字段分隔符
    1407有效期限
    101服务code
    40100亿轨道2自由裁量数据
    ˚F填充
  9f67 01轨道2号的空中交通管制数字
    04
  9f69 0F UDOL
    9f6a 04 UN predictable号(数字)
    9f7e 01手机支持指示符
    9f02 06授权量(数字)
    5f2a 02交易币code
    9f1a 02端子国家code
 

所以该卡的确实提供UDOL。因此,在COMPUTE加密校验命令已被相应的调整:

 字节[] computeCC =新的字节[] {
    (字节)0x80的,// CLA =专利
    (字节)0x2A,// INS = COMPUTE加密校验
    (字节)为0x8E,// P1
    (字节)0x80的,// P2
    (字节)为0x0F,// LC
    // 9f6a 04 UN predictable号(数字)
    (字节)为0x00,(字节)为0x00,(字节)为0x00,(字节)×12,//根据联合国/ ATC位图和ATC位数两个数字:6  -  4 = 2
    // 9f7e 01手机支持指示符
    (字节)为0x00,//不需要脱机PIN,没有移动支持
    // 9f02 06授权量(数字)
    (字节)为0x00,(字节)为0x00,(字节)为0x00,(字节)为0x00,(字节)为0x01,(字节)为0x00,// 1.00
    // 5f2a 02交易币code
    (字节)×09(字节)0x78,//欧元
    // 9f1a 02端子国家code
    (字节)为0x00,(字节)0X40,//奥地利
    (字节)为0x00,//乐
};
响应= isoDep.transceive(computeCC);
 

I'm trying to emulate a PoS, point of sale :), system and complete a transaction with Google wallet running on a 2013 Nexus 7 (no secure element) v4.4.2.

My PoS prototype is also running on a 2013 Nexus 7 v4.4.2.

I'm able to get NFC responses from the 2PAY_SYS_DDF01 request. I'm able to select the MasterCard application ID. I'm able to get Processing Options. When I Read Records it doesn't look like Google wallet is returning all the mandatory EMV fields. And finally when I request the Generate AC command it always returns 6D00 unsupported.

Area of the code that is a problem:

//set P1 to '40', to request an Transaction Certificate (offline transaction) 
//and execute the Generate AC command.

byte[] generateAC = new byte[] {(byte)0x80, (byte)0xAE, 0x40, 0x00,
                0x1D,                               //data length
                0x00, 0x00, 0x00, 0x00, 0x00, 0x01, //amount1
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //amount2
                0x08, 0x40,                         //term country
                0x00, 0x00, 0x00, 0x00, 0x00,       //tvr
                0x09, 0x62,                         //tx curr
                0x14, 0x04, 0x1B,                   //tx date
                0x00,                               //tx type
                0x12, 0x34, 0x56, 0x78,             //random
                0x00};                              //le
response = isoDep.transceive(generateAC);

I was following Tim Beckers video https://www.youtube.com/watch?v=qqobg1-HrfY approx. 46 minutes in. and Tim Beckers code sample: https://github.com/a2800276/29c3/blob/master/smartshell.rb

UPDATE:

The response to the GPO command (80 a8 00 00 02 83 00 00) is

770a820200009404080101009000

77 Response Message Template Format 2
    82 Application Interchange Profile
        0000
    94 Application File Locator (AFL)
        08010100

UPDATE:

I tried:

byte[] computeCC = new byte[] {
(byte)0x80, // CLA = proprietary
(byte)0x2A, // INS = COMPUTE CRYPTOGRAPHIC CHECKSUM
(byte)0x8E, // P1
(byte)0x80, // P2
(byte)0x04, // Lc
(byte)0x00, 0x00, (byte)0x00, (byte)0x99, // Unpredicatable Number (numeric)
(byte)0x00, // Le
};
response = isoDep.transceive(computeCC);

hoping to at least get an error that indicated the wrong unpredictable number but I got 6700 incorrect length returned.

Earlier I got a response to Read Record 00 B2 01 0C 00 Part of that response is Card Authentication Related Data [9F69]: Data (Binary): XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX fDDA Version Number: 9F (Card) Unpredictable Number: 6A 04 9F 7E

So I tried that Unpredictable number

byte[] computeCC = new byte[] {
(byte)0x80, // CLA = proprietary
(byte)0x2A, // INS = COMPUTE CRYPTOGRAPHIC CHECKSUM
(byte)0x8E, // P1
(byte)0x80, // P2
(byte)0x04, // Lc
(byte)0x6A, 0x04, (byte)0x9F, (byte)0x7E, // Unpredicatable Number (numeric)
(byte)0x00, // Le
};
response = isoDep.transceive(computeCC);

But I still get 6700 wrong length

UPDATE:

The response to READ RECORD (Record = 1, SFI = 1) command (00 B2 01 0C 00) is:

70 7c 9f 6c 02
00 01 9f 62 06
00 00 00 00 00
38 9f 63 06 00
00 00 00 03 c6
56 29 42 35 33
39 36 XX XX XX
XX 31 XX XX 39
XX XX XX XX 5e
20 2f 5e 31 34
30 37 31 30 31
34 30 31 30 30
30 30 30 30 30
30 30 30 9f 64
01 04 9f 65 02
00 38 9f 66 02
03 c6 9f 6b 13
53 96 XX XX 1X
X9 XX XX d1 40
71 01 40 10 00
00 00 00 0f 9f
67 01 04 9f 69
0f 9f 6a 04 9f
7e 01 9f 02 06
5f 2a 02 9f 1a
02 90 00

--------------------------TLV------------------------------- 
Output:
READ RECORD Response Message Template [70]:
    Card Transaction Qualifiers (CTQ) [9F6C]:
    Data (Binary):  00 01 
Bit flags set:
    1Bxb8: 0 - Online PIN not Required
    1Bxb7: 0 - Signature Not Required
    1Bxb6: 0 - Not applicable: Go Online if Offline Data Authentication     Fails and Reader is online capable.
    1Bxb5: 0 - Not applicable: Switch Interface if Offline Data     Authentication fails and Reader supports VIS.
    1Bxb4: 0 - Not applicable: Go Online if Application Expired
    1Bxb3: 0 - Not applicable: Switch Interface for Cash Transactions
    1Bxb2: 0 - Not applicable: Switch Interface for Cashback Transactions
    1Bxb1: 0 - RFU
    2Bxb8: 0 - Consumer Device CVM not Performed
    2Bxb7: 0 - Card doesn't support Issuer Update Processing at the POS
    2Bxb6: 0 - RFU
    2Bxb5: 0 - RFU
    2Bxb4: 0 - RFU
    2Bxb3: 0 - RFU
    2Bxb2: 0 - RFU
    2Bxb1: 1 - RFU
PCVC3 (Track1) [9F62]:
    Data (Binary):  00 00 00 00 00 38 
Offline Counter Initial Value [9F63]:
    Data (Binary):  00 00 00 00 03 C6 
Track 1 Data [56]:

    Data (ASCII):   B5396XXXXXXXXXXXX^ /^14071014010000000000
NATC (Track1) [9F64]:
    Data (Binary):  04 
PCVC3 (Track2) [9F65]:
    Data (Binary):  00 38 
Terminal Transaction Qualifiers (TTQ) [9F66]:
    Data (Binary):  03 C6 
Card CVM Limit [9F6B]:
    Data (Binary):  53 96 48 50 17 69 62 32 D1 40 71 01 40 10 00 00 00 00 0F 
MSD Offset [9F67]:
    Data (Binary):  04 
Card Authentication Related Data [9F69]:
    Data (Binary):  9F 6A 04 9F 7E 01 9F 02 06 5F 2A 02 9F 1A 02 
fDDA Version Number: 9F
(Card) Unpredictable Number: 6A 04 9F 7E
Card Transaction Qualifiers: 01 9F
----------------------------------------

解决方案

The response to the GET PROCESSING OPTIONS command indicates the following Application Interchange Profile (AIP):

82 Application Interchange Profile
    0000

Google Wallet is basically a MasterCard (EMV contactless kernel 2), so decoding the AIP according to the rules of Kernel 2 results in the following:

Byte 1, b7 = 0: no SDA supported
        b6 = 0: no DDA supported
        b5 = 0: no cardholder verification supported
        b4 = 0: no terminal risk management to be performed
        b3 = 0: no issuer authentication supported
        b2 = 0: no on-device cardholder verification supported
        b1 = 0: no CDA supported
Byte 2, b8 = 0: no EMV mode supported

The important part is byte 2, bit 8: It indicates that your card does not support EMV mode. Hence, your card/Google Wallet is a PayPass card that supports only Mag-Stripe mode. Therefore, you cannot authenticate transactions using GENERATE AC. Instead, you can only let the card generate dynamic card verification codes (CVC3) using COMPUTE CRYPTOGRAPHIC CHECKSUM:

byte[] computeCC = new byte[] {
    (byte)0x80, // CLA = proprietary
    (byte)0x2A, // INS = COMPUTE CRYPTOGRAPHIC CHECKSUM
    (byte)0x8E, // P1
    (byte)0x80, // P2
    (byte)0x04, // Lc
    (byte)0xWW, (byte)0xXX, (byte)0xYY, (byte)0xZZ, // Unpredicatable Number (numeric)
    (byte)0x00, // Le
};
response = isoDep.transceive(computeCC);

Note that the data field of the COMPUTE CRYPTOGRAPHIC CHECKSUM command must be filled with values according to the UDOL (in case there is no UDOL, the default UDOL is 9F6A04, indicating the unpredictable number, numeric).

The unpredictable number (numeric) is a BCD coded number in the range that is defined by the mag-stripe data file (see the AFL). In the past, for Google Wallet, this was a value between 0 and 99 (i.e. WW='00', XX='00', YY='00', ZZ='00'..'99').

UPDATE:

The data read from the card decodes as follows:

70 7c
  9f6c 02    Mag-stripe application version number = Version 1
    00 01
  9f62 06    Track 1 bit map for CVC3
    00 00 00 00 00 38
  9f63 06    Track 1 bit map for UN and ATC
    00 00 00 00 03 c6
  56 29      Track 1 data
    42         ISO/IEC 7813 structure "B" format
    35333936 XXXXXXXX 31XXXX39 XXXXXXXX    PAN (ASCII)
    5e         Field separator "^"
    202f       Cardholder name " /" (empty, see MC requirements)
    5e         Field separator "^"
    31343037   Expiry date "14"/"07"
    313031     Service code "101"
    34303130303030303030303030    Track 1 discretionary data
  9f64 01    Track 1 number of ATC digits
    04
  9f65 02    Track 2 bit map for CVC3
    00 38
  9f66 02    Track 2 bit map for UN and ATC
    03 c6
  9f6b 13    Track 2 data
    5396 XXXX 1XX9 XXXX    PAN (BCD)
    d          Field separator
    1407       Expiry date
    101        Service code
    4010000000000    Track 2 discretionary data
    f          Padding
  9f67 01      Track 2 number of ATC digits
    04
  9f69 0f      UDOL
    9f6a 04      Unpredictable number (numeric)
    9f7e 01      Mobile support indicator
    9f02 06      Amount authorized (numeric)
    5f2a 02      Transaction currency code
    9f1a 02      Terminal country code

So the card does provide a UDOL. Therefore, the COMPUTE CRYPTOGRAPHIC CHECKSUM command has to be adapted accordingly:

byte[] computeCC = new byte[] {
    (byte)0x80, // CLA = proprietary
    (byte)0x2A, // INS = COMPUTE CRYPTOGRAPHIC CHECKSUM
    (byte)0x8E, // P1
    (byte)0x80, // P2
    (byte)0x0F, // Lc
    // 9f6a 04      Unpredictable number (numeric)
    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x12, // two digits according to UN/ATC bit map and number of ATC digits: 6 - 4 = 2
    // 9f7e 01      Mobile support indicator
    (byte)0x00, // no offline PIN required, no mobile support
    // 9f02 06      Amount authorized (numeric)
    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, // 1.00
    // 5f2a 02      Transaction currency code
    (byte)0x09, (byte)0x78, // Euro
    // 9f1a 02      Terminal country code
    (byte)0x00, (byte)0x40, // Austria
    (byte)0x00, // Le
};
response = isoDep.transceive(computeCC);

这篇关于Android的isoDep.transceive上产生AC命令总是返回6D00不受支持的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆