Delphi环境下智能卡APDU通信过程开发的技术咨询
Delphi智能卡APDU通信实现指南
所需依赖
- 直接调用Windows系统自带的
WinSCard.dll,Delphi自带WinSCard单元已封装好所有接口,无需额外引入第三方库或DLL
实现步骤
- 初始化智能卡资源管理器上下文,枚举当前可用的读卡器列表
- 连接指定读卡器上的智能卡,协商使用T0/T1通信协议
- 组装SELECT APDU指令,参数完全匹配需求
- 调用传输接口发送APDU,接收卡返回的响应数据与状态码
- 校验状态码是否为
0x9000,确认选卡成功后后续所有APDU都复用当前连接发送 - 通信完成后释放连接与上下文资源
核心代码示例
uses WinSCard, Windows, SysUtils; function SelectTargetApplet(const ReaderName: string; out hCard: THandle; out ActiveProto: DWORD): Boolean; var hContext: SCARDCONTEXT; dwRet: DWORD; bSendBuf: array[0..22] of Byte; bRecvBuf: array[0..255] of Byte; dwRecvLen: DWORD; SW: WORD; begin Result := False; hCard := 0; ActiveProto := 0; // 1. 初始化SCard上下文 dwRet := SCardEstablishContext(SCARD_SCOPE_USER, nil, nil, @hContext); if dwRet <> SCARD_S_SUCCESS then Exit; try // 2. 连接智能卡 dwRet := SCardConnect(hContext, PChar(ReaderName), SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 or SCARD_PROTOCOL_T1, hCard, @ActiveProto); if dwRet <> SCARD_S_SUCCESS then Exit; // 3. 组装选卡APDU指令,完全匹配需求参数 bSendBuf[0] := $00; // Class bSendBuf[1] := $A4; // Instruction: SELECT bSendBuf[2] := $04; // P1: 按AID选择 bSendBuf[3] := $00; // P2: 匹配第一个符合条件的Applet bSendBuf[4] := $10; // Lc: 后续Data段长度 // AID数据部分 bSendBuf[5] := $A0; bSendBuf[6] := $00; bSendBuf[7] := $00; bSendBuf[8] := $07; bSendBuf[9] := $48; bSendBuf[10] := $46; bSendBuf[11] := $4A; bSendBuf[12] := $49; bSendBuf[13] := $2D; bSendBuf[14] := $54; bSendBuf[15] := $61; bSendBuf[16] := $78; bSendBuf[17] := $43; bSendBuf[18] := $6F; bSendBuf[19] := $72; bSendBuf[20] := $65; bSendBuf[21] := $00; // Le: 期望返回的最大数据长度 // 4. 发送APDU指令 dwRecvLen := Length(bRecvBuf); dwRet := SCardTransmit(hCard, SCARD_PCI_T0, @bSendBuf, Length(bSendBuf), nil, @bRecvBuf, @dwRecvLen); if dwRet <> SCARD_S_SUCCESS then Exit; // 5. 校验返回状态码 if dwRecvLen >= 2 then begin SW := (bRecvBuf[dwRecvLen-2] shl 8) or bRecvBuf[dwRecvLen-1]; Result := (SW = $9000); // 0x9000表示选卡成功 end; // 注意:hCard需保留用于后续业务APDU发送,不要在此处断开连接 finally // 上下文可根据业务需要保留或释放,此处示例直接释放 SCardReleaseContext(hContext); end; end;
常见返回状态码说明
0x9000:选卡成功,后续可直接发送业务APDU0x6A82:未找到对应AID的Applet,检查AID是否填写正确0x6700:APDU长度错误,检查指令组装逻辑是否异常0x6985:使用条件不满足,通常为卡处于锁定状态
内容的提问来源于stack exchange,提问作者q1werty
相关产品推荐
相关产品推荐

