1

我正在研究一个从智能卡读取数据和将数据写入智能卡的项目。正在使用的读卡器ACR38U-H1来自ACS. 按照他们的APDU命令,我能够访问卡并读取一些数据。但是我怀疑我仍然无法读取里面的确切数据,因为我总是得到对命令的响应APDU 0x6e 0x00, 0x00而不是0x90 0x00.

我究竟做错了什么?
也许问题出在智能卡上?

Python代码:

#! /usr/bin/env python
from smartcard.scard import *
import smartcard.util


SELECT = [
    #0xA0, 0xA4, 0x00, 0x00, 0x02, 0x3F, 0x00
    0XFF, 0xA4, 0x00, 0x00, 0x01, 0x05
]

COMMAND = [
    0x00, 0xC0, 0x00, 0x00, 0x00, 0x0B
]

try:
    hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER)
    if hresult != SCARD_S_SUCCESS:
        raise Exception('Failed to establish context : ' +
            SCardGetErrorMessage(hresult))
    print 'Context established!'

    try:
        hresult, readers = SCardListReaders(hcontext, [])
        if hresult != SCARD_S_SUCCESS:
            raise Exception('Failed to list readers: ' +
                SCardGetErrorMessage(hresult))
        print 'PCSC Readers:', readers

        if len(readers) < 1:
            raise Exception('No smart card readers')

        reader = readers[0]
        print "Using reader:", reader

        try:
            hresult, hcard, dwActiveProtocol = SCardConnect(hcontext, reader,
                SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1 | SCARD_PROTOCOL_T1)
            if hresult != SCARD_S_SUCCESS:
                raise Exception('Unable to connect: ' +
                    SCardGetErrorMessage(hresult))
            print 'Connected with active protocol', dwActiveProtocol

            try:
                hresult, response = SCardTransmit(hcard, dwActiveProtocol,
                    SELECT)
                if hresult != SCARD_S_SUCCESS:
                    raise Exception('Failed to transmit: ' +
                        SCardGetErrorMessage(hresult))
                print 'Select: ' + smartcard.util.toHexString(response,
                    smartcard.util.HEX)
#==========================================================================
                hresult, response = SCardTransmit(hcard, dwActiveProtocol,
                    COMMAND)
                if hresult != SCARD_S_SUCCESS:
                    raise Exception('Failed to transmit: ' +
                        SCardGetErrorMessage(hresult))
                print 'Command: ' + smartcard.util.toHexString(response,
                    smartcard.util.HEX)
# =========================================================================
            finally:
                hresult = SCardDisconnect(hcard, SCARD_UNPOWER_CARD)
                if hresult != SCARD_S_SUCCESS:
                    raise Exception('Failed to disconnect: ' +
                        SCardGetErrorMessage(hresult))
                print 'Disconnected'

        except Exception, message:
            print "Exception:", message

    finally:
        hresult = SCardReleaseContext(hcontext)
        if hresult != SCARD_S_SUCCESS:
            raise Exception('Failed to release context: ' +
                    SCardGetErrorMessage(hresult))
        print 'Released context.'

except Exception, message:
    print "Exception:", message

此代码的结果:

Context established!
PCSC Readers: ['ACS ACR38U-CCID 00 00']
Using reader: ACS ACR38U-CCID 00 00
Connected with active protocol 2
Select: 0x6E 0x00
Command: 0x67 0x00
Disconnected
Released context.

打开工具的结果:

[17:06:00]:~$ opensc-tool -s ff:a4:00:00:01:05
Using reader with a card: ACS ACR38U-CCID 00 00
Sending: FF A4 00 00 01 05 
Received (SW1=0x6E, SW2=0x00)
4

2 回答 2

0
SELECT = [
    #0xA0, 0xA4, 0x00, 0x00, 0x02, 0x3F, 0x00
    0XFF, 0xA4, 0x00, 0x00, 0x01, 0x05
]

在这里,您似乎正在尝试选择 MF(注释 # 命令上的 AID = 3F00) 命令似乎错误,因为没有 AID 的长度为 1 字节,请检查您的命令

 0XFF, 0xA4, 0x00, 0x00, 0x01, 0x05 // check it.

并且不支持获得 6E 00

您的另一个命令是 C0 - GET RESPONSE,

COMMAND = [
    0x00, 0xC0, 0x00, 0x00, 0x00, 0x0B
]

此命令用于从先前命令指定长度的卡中获取响应,返回代码如 - 61 XX 和 APDU 序列应为 CLASS、INS、P1、P2、Le //请检查您的获取响应命令

这里 Get Response 给出 6700 ,这似乎是正确的,因为先前的命令已经失败并且卡没有任何东西可以返回它所以无法返回 Le 数据(0x0B - 假设它是你的 Le)

我建议,在发出任何命令之前先了解你的卡,它似乎是一张专有卡,所以你应该在发送命令之前知道文件结构/CLASS 字节使用,当你用正确的 CLA 值射击时,希望你不会得到 - CLA 不支持错误。

希望这些信息有助于识别问题。

于 2016-05-25T05:50:57.613 回答
0

您正在使用SELECT_CARD_TYPEAPDU 命令 (0xFF00000101),该命令旨在与I2C 存储卡(具体最高 16 kb)一起使用——请参阅阅读器参考手册中的第 9.3.1.1 节。

SELECT_CARD_TYPE命令(CLA设置为0xFF)不是针对卡,而是针对读卡器(由于卡不使用 I2C 而拒绝它)。

您的卡是讲T=1 协议的微处理器卡,因此您需要使用“普通”ISO 7816 APDU——应该在您的卡文档中指定哪些。

尽管如此,有一个Smart Card Shell 3工具的脚本,它似乎可以读取(并以有限的方式模拟)FOMS 卡(我没有尝试过)。

鉴于脚本源,卡片似乎支持标准 ISO 7816-4SELECT和APDU 命令,这些命令在和READ_BINARY后面使用。new CardFile()CardFile.readBinary()

祝你好运!

免责声明:我既没有使用任何 FOMS 卡,也没有使用 scsh3 工具。

于 2016-06-08T14:47:09.740 回答