通过Android USB主机与智能卡读卡器进行通信 [英] Communicate with smartcard reader through Android USB host

查看:212
本文介绍了通过Android USB主机与智能卡读卡器进行通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试向智能卡发送命令.我使用了 Gemalto IDBridge CT30(PC TWIN阅读器) IDBridge K30 连接到通过USB的Android设备.

I'm trying to send a command to a smart card. I use a Gemalto IDBridge CT30 (PC TWIN reader) and a IDBridge K30 connected to the Android device over USB.

我尝试通过USB发送SELECT APDU命令:

I try to send a SELECT APDU command over USB:

boolean claim = openedConnection.claimInterface(usbInterface, true);
byte[] data = new byte[]{
        (byte) 0x00, (byte) 0xA4, (byte) 0x04, (byte) 0x0C,
        (byte) 0x07, (byte) 0xA0, (byte) 0x00, (byte) 0x00,
        (byte) 0x01, (byte) 0x18, (byte) 0x45, (byte) 0x4E};

此后,我得到一个答案:

After that I receive an answer:

final int dataTransferred = this.openedConnection.bulkTransfer(endPointOut, data, data.length, TIMEOUT_MS);
if(!(dataTransferred == 0 || dataTransferred == data.length)) {
    throw new Exception("Error durring sending command [" + dataTransferred + " ; " + data.length + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}

final byte[] responseBuffer = new byte[endPointIn.getMaxPacketSize()];
final int dataTransferred = this.openedConnection.bulkTransfer(this.endPointIn, responseBuffer, responseBuffer.length, TIMEOUT_MS);
Console.writeLine("USB Retrieve: " + dataTransferred + " " + responseBuffer.length);
if(dataTransferred >= 0){
    return responseBuffer;
}
throw new Exception("Error durring receinving response [" + dataTransferred + "]");

那个答案是

0x00 0x00 0x00 0x00 0x00 0xA0 0x00 0x41 0x03 0x00

但是,我应该根据我做错了什么?有谁能够帮我?我使用正确的方法吗?我没有使用javax.smartcardio的默认包类.我直接使用USB接口类(例如 UsbDevice )./p>

What am I doing wrong? Can anybody help me? Do I use the correct approach? I'm not using the default package classes of javax.smartcardio. I use the USB interface classes (e.g. UsbDevice) directly.

推荐答案

您的阅读器设备通过USB接口说出CCID.您不能简单地在扩展端点上发送APDU(智能卡命令),并期望在扩展端点上接收响应APDU.相反,您需要实现CCID设备类协议(请参见 USB设备类规范).步骤类似于:

Your reader device speaks CCID over the USB interface. You cannot simply send an APDU (smartcard command) over the bulk-out endpoint and expect to receive a response APDU over the bulk-in endpoint. Instead you need to implement the CCID device class protocol (see USB Device Class Specifications). The steps are something like:

  1. 发送PC_to_RDR_IccPowerOn命令以激活卡.
  1. Send PC_to_RDR_IccPowerOn command to activate the card.

62 00000000 00 00 00 0000 
|  |        |  |  |  |    |
|  |        |  |  |  |    \--> Empty data field
|  |        |  |  |  \-------> Unused, set to 0x0000
|  |        |  |  \----------> Power select: 0x00 indicates automatic selection
|  |        |  \-------------> Sequence number (increment for each command)
|  |        \----------------> Slot number (seems to be zero for your device)
|  \-------------------------> Length of data field (LSB first)
\----------------------------> Message type: 0x62 indicates PC_to_RDR_IccPowerOn

  • 通过RDR_to_PC_DataBlock接收ATR.

  • Receive the ATR through RDR_to_PC_DataBlock.

    
    80 18000000 00 00 00 00 00 3BBF11008131FE45455041000000000000000000000000F1 
    |  |        |  |  |  |  |  |
    |  |        |  |  |  |  |  \--> Data field: ATR
    |  |        |  |  |  |  \-----> Level parameter
    |  |        |  |  |  \--------> Error register (should be zero on success)
    |  |        |  |  \-----------> Status register (should be zero on success)
    |  |        |  \--------------> Sequence number (matches the sequence number of the command)
    |  |        \-----------------> Slot number (matches the slot number of the command)
    |  \--------------------------> Length of data field (LSB first)
    \-----------------------------> Message type: 0x80 indicates RDR_to_PC_DataBlock
    

  • 发送命令APDU包装到PC_to_RDR_XfrBlock命令中

  • Send command APDU wrapped into PC_to_RDR_XfrBlock command

    
    6F 0C000000 00 01 00 0000 00A4040C07A000000118454E
    |  |        |  |  |  |    |
    |  |        |  |  |  |    \--> Data field: Command APDU
    |  |        |  |  |  \-------> Level parameter (0x0000 for normal length APDUs)
    |  |        |  |  \----------> Block waiting timeout
    |  |        |  \-------------> Sequence number (increment for each command)
    |  |        \----------------> Slot number (seems to be zero for your device)
    |  \-------------------------> Length of data field (LSB first)
    \----------------------------> Message type: 0x6F indicates PC_to_RDR_XfrBlock
    

  • 通过RDR_to_PC_DataBlock接收响应APDU.

  • Receive response APDU through RDR_to_PC_DataBlock.

    
    80 02000000 00 01 00 00 00 9000 
    |  |        |  |  |  |  |  |
    |  |        |  |  |  |  |  \--> Data field: Response APDU
    |  |        |  |  |  |  \-----> Level parameter
    |  |        |  |  |  \--------> Error register (should be zero on success)
    |  |        |  |  \-----------> Status register (should be zero on success)
    |  |        |  \--------------> Sequence number (matches the sequence number of the command)
    |  |        \-----------------> Slot number (matches the slot number of the command)
    |  \--------------------------> Length of data field (LSB first)
    \-----------------------------> Message type: 0x80 indicates RDR_to_PC_DataBlock
    

  • 对于每个APDU交换重复步骤3和4(不要忘记增加序列号).
  • 由于ATR将T = 1指示为第一协议,因此您可能需要将APDU包装到T = 1 TPDU中(取决于阅读器配置).第一个APDU的I块如下所示:

    Since the ATR indicates T=1 as first protocol, you might need to wrap your APDU into T=1 TPDUs (depending on the reader configuration). The I-block for the first APDU would look something like:

    
    00 00 0C 00A4040C07A000000118454E 15
    |  |  |  |                        |
    |  |  |  |                        \--> LRC (due to missing TC in ATR): XOR checksum over all other bytes
    |  |  |  \---------------------------> INF: APDU
    |  |  \------------------------------> LEN: length of INF field
    |  \---------------------------------> PCB: toggle between 0x00 and 0x40 for every other I-block
    \------------------------------------> NAD: node addressing
    

    因此您的PC_to_RDR_XfrBlock命令如下所示:

    So your PC_to_RDR_XfrBlock command would look like:

    
    6F 10000000 00 01 00 0000  00 00 0C 00A4040C07A000000118454E 15
    

    然后您将收到用I块或R或S块包装的答案,表明有必要进行特殊/错误处理.

    You would then either receive your answer wrapped in an I-block or an R- or S-block indicating that some special/error treatment is necessary.

    这篇关于通过Android USB主机与智能卡读卡器进行通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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