使用 Chilkat DLL 函数“TransmitHex()”时出现智能卡错误 0x8010002f

问题描述 投票:0回答:1

我用:

  • 金雅拓 IDBridge K30
  • Windows 10
  • 德尔福
  • Chilkat Delphi DLL

我需要从智能卡中获取 ICCID,但是当我使用 Chilkat DLL 中的

TransmitHex()
时,我总是收到错误代码:

0x8010002f

首先我尝试了 Chilkat 的示例:https://www.example-code.com/delphiDll/pcsc_get_card_uid.asp

procedure TForm1.Button1Click(Sender: TObject);
var
  scard: HCkSCard;
  success: Boolean;
  json: HCkJsonObject;
  name: PWideChar;
  state: PWideChar;
  vendorName: PWideChar;
  systemName: PWideChar;
  cardAtr: PWideChar;
  cardWindowsMiniDriver: PWideChar;
  cardWindowsCryptoProvider: PWideChar;
  cardWindowsKeyStorageProvider: PWideChar;
  serialNumber: PWideChar;
  i: Integer;
  count_i: Integer;
  bdRecv: HCkBinData;
  numBytes: Integer;
begin
  // This example requires the Chilkat API to have been previously unlocked.
  // See Global Unlock Sample for sample code.

  scard := CkSCard_Create();

  // First establish a context to the PC/SC Resource Manager
  success := CkSCard_EstablishContext(scard,'user');
  if (success = False) then
    begin
      Memo1.Lines.Add(CkSCard__lastErrorText(scard));
      Exit;
    end;

  // Use your own smart card reader name here.
  success := CkSCard_Connect(scard, CkSCard__connectedReader(scard),'shared','no_preference');
  if (success = False) then
    begin
      Memo1.Lines.Add(CkSCard__lastErrorText(scard));
      Exit;
    end;

  Memo1.Lines.Add('Connected reader: ' + CkSCard__connectedReader(scard));
  Memo1.Lines.Add('Active protocol: ' + CkSCard__activeProtocol(scard));
  Memo1.Lines.Add('ATR: ' + CkSCard__cardAtr(scard));
  Memo1.Lines.Add('Reader Status: ' + CkSCard__readerStatus(scard));

  //  Send the APDU command 0xFF, 0xCA, 0x00, 0x00, 0x00
  bdRecv := CkBinData_Create();
  success := CkSCard_TransmitHex(scard,CkSCard__activeProtocol(scard),'FFCA000000',bdRecv,32);
  if (success = True) then
    begin

      Memo1.Lines.Add('Received: ' + CkBinData__getEncoded(bdRecv,'hex'));

      // The UID is the returned data without the final 2 bytes.
      numBytes := CkBinData_getNumBytes(bdRecv);
      if (numBytes > 2) then
        begin
          Memo1.Lines.Add('UID: ' + CkBinData__getEncodedChunk(bdRecv,0,numBytes - 2,'hex'));
        end;

    end
  else
    begin
      Memo1.Lines.Add(CkSCard__lastErrorText(scard));
    end;

  // Disconnect from this reader.
  success := CkSCard_Disconnect(scard,'leave');
  if (success = False) then
    begin
      Memo1.Lines.Add(CkSCard__lastErrorText(scard));
    end;

  // Applications should always release the context when finished.
  success := CkSCard_ReleaseContext(scard);
  if (success = False) then
    begin
      Memo1.Lines.Add(CkSCard__lastErrorText(scard));
    end;

  CkSCard_Dispose(scard);
  CkBinData_Dispose(bdRecv);
end;

我得到的是:

UnlockBundle: 
Oh yeah
Test
Test1
Test2
0: Gemalto USB SmartCard Reader 0
Connected reader: Gemalto USB SmartCard Reader 0
Test3
Test4
Connected reader: Gemalto USB SmartCard Reader 0
Active protocol: T0
ATR: 3B9F96801FC68031E073FE211B66D00221AB11180180
Reader Status: specific
ChilkatLog:
  TransmitHex(1844ms):
    DllDate: Jun 29 2024
    ChilkatVersion: 9.5.0.99
    UnlockStatus: 1
    Architecture: Little Endian; 32-bit
    Language: Delphi DLL
    VerboseLogging: 1
    transmit(1844ms):
      PcscErrorCode: 0x8010002f
      SCardTransmit failed.
    --transmit
    Failed.
  --TransmitHex
--ChilkatLog


Test5
Test6
Test7

后来我发现需要PIN的智能卡没有UID。但我猜这会导致不同的错误。

我还尝试了一些方法来获取我需要的 ICCID:

procedure TForm1.Button1Click(Sender: TObject);
var
  scard: HCkSCard;
  success: Boolean;
  json: HCkJsonObject;
  name: PWideChar;
  state: PWideChar;
  vendorName: PWideChar;
  systemName: PWideChar;
  cardAtr: PWideChar;
  cardWindowsMiniDriver: PWideChar;
  cardWindowsCryptoProvider: PWideChar;
  cardWindowsKeyStorageProvider: PWideChar;
  serialNumber: PWideChar;
  i: Integer;
  count_i: Integer;
  bdRecv: HCkBinData;
  numBytes: Integer;
begin
  // This example requires the Chilkat API to have been previously unlocked.
  // See Global Unlock Sample for sample code.

  scard := CkSCard_Create();

  // First establish a context to the PC/SC Resource Manager
  success := CkSCard_EstablishContext(scard,'user');
  if (success = False) then
    begin
      Memo1.Lines.Add(CkSCard__lastErrorText(scard));
      Exit;
    end;

  // Use your own smart card reader name here.
  success := CkSCard_Connect(scard, CkSCard__connectedReader(scard),'shared','no_preference');
  if (success = False) then
    begin
      Memo1.Lines.Add(CkSCard__lastErrorText(scard));
      Exit;
    end;

  Memo1.Lines.Add('Connected reader: ' + CkSCard__connectedReader(scard));
  Memo1.Lines.Add('Active protocol: ' + CkSCard__activeProtocol(scard));
  Memo1.Lines.Add('ATR: ' + CkSCard__cardAtr(scard));
  Memo1.Lines.Add('Reader Status: ' + CkSCard__readerStatus(scard));

  //Get ICCID
  //  Send the APDU command 0xA0, 0xA4, 0x00, 0x00, 0x02, 0x3F, 0x00
  bdRecv := CkBinData_Create();
  success := CkSCard_TransmitHex(scard,CkSCard__activeProtocol(scard),'A0A40000023F00',bdRecv,32);
  if (success = True) then
    begin

      Memo1.Lines.Add('Received: ' + CkBinData__getEncoded(bdRecv,'hex'));

      // Select MF
      numBytes := CkBinData_getNumBytes(bdRecv);
      if (numBytes > 2) then
        begin
          Memo1.Lines.Add('Select MF: ' + CkBinData__getEncodedChunk(bdRecv,0,numBytes - 2,'hex'));
        end;

    end
  else
    begin
      Memo1.Lines.Add(CkSCard__lastErrorText(scard));
    end;

  //  Send the APDU command 0xA0, 0xA4, 0x00, 0x00, 0x02, 0x2F, 0xE2
  bdRecv := CkBinData_Create();
  success := CkSCard_TransmitHex(scard,CkSCard__activeProtocol(scard),'A0A40000022FE2',bdRecv,32);
  if (success = True) then
    begin

      Memo1.Lines.Add('Received: ' + CkBinData__getEncoded(bdRecv,'hex'));

      // Select ICCID
      numBytes := CkBinData_getNumBytes(bdRecv);
      if (numBytes > 2) then
        begin
          Memo1.Lines.Add('Select ICCID: ' + CkBinData__getEncodedChunk(bdRecv,0,numBytes - 2,'hex'));
        end;

    end
  else
    begin
      Memo1.Lines.Add(CkSCard__lastErrorText(scard));
    end;

  //  Send the APDU command 0xA0, 0xB0, 0x00, 0x00, 0x0A
  bdRecv := CkBinData_Create();
  success := CkSCard_TransmitHex(scard,CkSCard__activeProtocol(scard),'A0B000000A',bdRecv,32);
  if (success = True) then
    begin

      Memo1.Lines.Add('Received: ' + CkBinData__getEncoded(bdRecv,'hex'));

      // Read the 10 bytes of ICCID EF
      numBytes := CkBinData_getNumBytes(bdRecv);
      if (numBytes > 2) then
        begin
          Memo1.Lines.Add('Read ICCID: ' + CkBinData__getEncodedChunk(bdRecv,0,numBytes - 2,'hex'));
        end;

    end
  else
    begin
      Memo1.Lines.Add(CkSCard__lastErrorText(scard));
    end;
  //END

  // Disconnect from this reader.
  success := CkSCard_Disconnect(scard,'leave');
  if (success = False) then
    begin
      Memo1.Lines.Add(CkSCard__lastErrorText(scard));
    end;

  // Applications should always release the context when finished.
  success := CkSCard_ReleaseContext(scard);
  if (success = False) then
    begin
      Memo1.Lines.Add(CkSCard__lastErrorText(scard));
    end;

  CkSCard_Dispose(scard);
  CkBinData_Dispose(bdRecv);
end;

但是错误结果还是一样。

delphi smartcard apdu chilkat
1个回答
0
投票

一些备注:

我假设您将 ICCID 理解为卡的唯一序列号。这些差异很大(对于给定的智能卡,您甚至可能根本无法获取它),并且获取它的方式也因卡而异。

第一个示例中的代码显然尝试的是发送特殊的 APDU(“FFCA..”)并期望 ICCID 作为响应。这是一个读者特定命令,可能是错误的。

第二个示例中的代码使用 CLA 字节

A0
,这对于您的卡来说可能是正确的,但您似乎没有提供提示,您实际上正在寻址哪张卡,因为 Gemalto IDBridge K30 是一个读卡器。

© www.soinside.com 2019 - 2024. All rights reserved.