在智能卡中选择DF(专用文件),返回错误6981

时间:2015-09-29 11:27:47

标签: smartcard apdu smartcard-reader cardreader

我已经编写了一个与智能卡通信的程序(Gemalto Company MPCOS applet)。 我可以成功连接到卡并传输命令和获取数据。

但是我有一个问题: 当我使用00 A4 01 00 02 02 00命令选择DF(专用文件)时, 它返回错误69 81(文件指示符不正确)。

这很奇怪,因为在此命令之后我使用另一个命令来获取此DF的子文件并返回成功61 12

command1(Select MPCOS Applet): 00 A4 04 00 10 A0 00 00 00 18 30 03 01 00 00 00 00 00 00 00 00
-> response: [97,18] (in decimal) or 6112 (in hex)

command2: 00 C0 00 00 12
-> response: [105,133,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] (in decimal) or
             69 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 (in hex)

command3(Select Root): 00 A4 00 00 02 3f 00
-> response: [97,18] (in decimal) or 6112 (in hex)

command4: 00 C0 00 00 12
-> response: [105,133,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] (in decimal) or
             69 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 (in hex)

command5(Select DF): 00 A4 01 00 02 02 00
-> response: [105,129] (in decimal) or 6981 (in hex)

command6(Select EF): 00 A4 02 00 02 02 01
-> response: [97,18] (in decimal) or 6112 (in hex)

command7: 00 C0 00 00 12
-> response: [105,133,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] (in decimal) or 
             69 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 (in hex)

2 个答案:

答案 0 :(得分:2)

如果您需要处理00A4010002020000响应,您可以使用SELECT命令APDU(即与之前相同,但使用 Le 字段)(您可以获得)它使用您可能已经知道的GET RESPONSE命令。)

或者,如果您不需要处理00A4010C020200响应,则可以使用P2=0x0C命令APDU(即与之前相同,但使用SELECT表示不需要响应数据)

根据您的意见,这种方法应该有效。

编辑>

这很奇怪,我刚刚在原生MPCOS卡上重现了你的情况(现在无法访问MPCOS applet):

00A40000023F00 -> 851080013F0038000000C100C100000000679000
00A40100020200 -> 6F15840E315041592E5359532E4444463031A5038801019000
00A40200020201 -> 85104302020105000040C000C0000000006B9000

注意:此跟踪不显示GET RESPONSE APDU交换。

所以我可能无法帮助你:(

答案 1 :(得分:1)

我发现了问题:

问题是由于调用SCardTransmit函数两次。实际上,一次获得响应长度,第二次执行命令并获得响应。

此双重调用导致错误6981:

function SCardTransmitFunc(aCallbackName, myCommand){
    var _SCARD_IO_REQUEST = new CONST.SCARD_IO_REQUEST;
    _SCARD_IO_REQUEST.dwProtocol = AProtocol;
    _SCARD_IO_REQUEST.cbPciLength =  CONST.SCARD_IO_REQUEST.size;  
    var myArrayCommand = hex2Dec(myCommand);        
    var command = TYPES.LPBYTE.targetType.array(myArrayCommand.length)(myArrayCommand);
    var commandLength = command.length;        
    var responseLength = TYPES.DWORD();
    var rez_SCT = SCardTransmit(cardHandle, _SCARD_IO_REQUEST.address(), command, commandLength, null, null, responseLength.address());
    var response = TYPES.LPBYTE.targetType.array(parseInt(responseLength.value))();
    var rez_SCT = SCardTransmit(cardHandle, _SCARD_IO_REQUEST.address(), command, commandLength, null, response, responseLength.address());
    var myResponse = "";//new Array();
    for(i = response.length - 2; i < response.length ; i++)
    {
        myResponse += dec2Hex(response[i]);
    }
}

并且更正的代码是:

function SCardTransmitFunc(aCallbackName, myCommand){
    var _SCARD_IO_REQUEST = new CONST.SCARD_IO_REQUEST;
    _SCARD_IO_REQUEST.dwProtocol = AProtocol;
    _SCARD_IO_REQUEST.cbPciLength =  CONST.SCARD_IO_REQUEST.size;  
    var myArrayCommand = hex2Dec(myCommand);
    var command = TYPES.LPBYTE.targetType.array(myArrayCommand.length)(myArrayCommand);
    var commandLength = command.length;
    var responseLength = TYPES.DWORD(1024);
    var response = TYPES.BYTE.array(parseInt(1024))();
    var rez_SCT = SCardTransmit(cardHandle, _SCARD_IO_REQUEST.address(), command, commandLength, null, response, responseLength.address());
    var myResponse = "";//new Array();
    var myLength = parseInt(responseLength.value);
    for(i = myLength - 2; i < myLength ; i++)
    {
        myResponse += dec2Hex(response[i]);
    }
}

我真的非常感谢@guidot的善意提示和亲爱的@vlp帮助