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

Selecting DF (Dedicated File) in Smart Card, Return Error 6981

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

但是我有一个问题: 当我使用 00 A4 01 00 02 02 00 命令到 select 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)

如果你需要处理SELECT,你可以使用00A4010002020000命令APDU(即和以前一样,但是有一个Le字段)响应(您可能已经知道,您可以使用 GET RESPONSE 命令获取它)。

或者如果你不需要处理 SELECT 回应。

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

编辑>

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

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

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

所以我可能帮不了你:(

我发现了问题:

问题是因为调用了两次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 的帮助