在未连接智能卡的情况下发送带有 winscard.dll (PC/SC) 的 APDU

Posted

技术标签:

【中文标题】在未连接智能卡的情况下发送带有 winscard.dll (PC/SC) 的 APDU【英文标题】:Sending APDU with winscard.dll (PC/SC) without a smart card connected 【发布时间】:2015-02-16 10:53:31 【问题描述】:

我正在尝试向读卡器本身而不是智能卡发送 APDU 命令。我正在使用的测试命令打开和关闭射频场。

如果我第一次连接到智能卡,此命令将通过 SCardTransmit 发送。但是一旦 RF 场关闭,卡就会断开连接,我无法发送另一个 APDU 来打开场。

基本上有什么方法可以在没有卡的情况下通过 pc/sc 发送 APDU。我想在读卡之前配置读卡器的某些部分。

提前致谢。

-----编辑-----

正如 FPGA Warrior 所说,我需要使用 SCardControl 向读卡器发送 APDU 命令。

到目前为止我已经完成的步骤:

使用带有 SCARD_SHARE_DIRECT 和 SCARD_PROTOCOL_UNDEFINED 的 SCardConnect 连接到“卡”。这将返回成功并为您提供卡句柄。

_lastError = SCardConnect(_hContext, _cardReaderName, dwShareMode, dwPreferredProtocols, ref phCard, ref _activeProtocol);

返回:0 和看起来像一个有效的 _hCard 句柄。

然后我调用 SCardControl

_lastError = SCardControl(phCard, CTL_code(3500), txBytes, (uint)txByte.Length, out rxBytes, (uint)rxAttr.Length, out rxLen);

我现在收到错误 ERROR_INVALID_HANDLE (0x6)。所以看起来我的 SCardConnect 没有返回有效的句柄,即使它没有返回错误。

附带说明要在设备上使用 PC_to_RDR_Escape 模式,如果您安装的驱动程序不允许,您可能需要编辑注册表以将其打开。 https://msdn.microsoft.com/en-us/library/windows/hardware/dn653571%28v=vs.85%29.aspx

【问题讨论】:

@MichelGutierrezRivas 想知道您是否解决了问题 【参考方案1】:

我不确定为什么要通过向卡发送 APDU 来配置读卡器。不应该这样。 SCardTransmit 用于向卡发送命令,如果没有卡,它将无法工作(除非您破解驱动程序,因此它实际上是插入了卡)。

您可能正在寻找以下 API 之一: https://msdn.microsoft.com/en-us/library/windows/desktop/aa375369(v=vs.85).aspx 它可以更直接地访问您的读卡器/卡。

指定您希望在阅读器上设置的配置可能会增加更改以获得对您有帮助的答案。

【讨论】:

【参考方案2】:

我可以通过使用 perl 绑定这些参数来做到这一点:

#connect witouth card in
$hCard = new Chipcard::PCSC::Card($hContext, $ReadersList[0], $Chipcard::PCSC::SCARD_SHARE_DIRECT, $Chipcard::PCSC::SCARD_PROTOCOL_RAW);  

#send any adpu
$cmd = Chipcard::PCSC::ascii_to_array("FF 00 40 F0 04 05 05 03 03");
$hCard->Transmit($cmd);

【讨论】:

【参考方案3】:

我在 SCardConnect 之后调用 SCardTransmit 也有类似的经历(从 SCardTransmit 接收 ERROR_INVALID_HANDLE )。

作为一项实验,将 Thread.Sleep(100) 放在 SCardTransmit 之后似乎会在 sleep 语句之后将错误代码从 0x6 更改为 SUCCESS(如在调试器中所见)。这不是一个解决方案,而是一个正确方向的提示。编写线程安全代码来处理 SCardControl 之后的语句会是更好的方法。

以下链接是一个很好的参考:

https://www.csharpstar.com/csharp-race-conditions-in-threading/

【讨论】:

【参考方案4】:

简单的方法是只打开/关闭智能卡读卡器是调用 SCardEstablishContext 来连接读卡器。 注意:这不会连接到智能卡:

    /// <summary>
    /// Native SCardEstablishContext function from winscard.dll
    /// </summary>
    /// <param name="dwScope"></param>
    /// <param name="pvReserved1"></param>
    /// <param name="pvReserved2"></param>
    /// <param name="phContext"></param>
    /// <returns></returns>
    [DllImport("winscard.dll", SetLastError=true)]
    internal    static  extern  int SCardEstablishContext(UInt32 dwScope,
        IntPtr pvReserved1,
        IntPtr pvReserved2,
        IntPtr phContext);

释放阅读器:这将关闭/释放当前进程的阅读器句柄。 注意:与智能卡没有任何关系。

    /// <summary>
    /// Native SCardReleaseContext function from winscard.dll
    /// </summary>
    /// <param name="hContext"></param>
    /// <returns></returns>
    [DllImport("winscard.dll", SetLastError=true)]
    internal static extern  int SCardReleaseContext(UInt32 hContext);

【讨论】:

以上是关于在未连接智能卡的情况下发送带有 winscard.dll (PC/SC) 的 APDU的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Java 中与智能卡交互?

连接金雅拓智能卡时出现错误 6

来自 O2Micro 阅读器上的 WINSCARD.DLL 方法 SCardTransmit 的未知响应以及响应长度信息

如何在未启用 USB 调试的情况下使用 adb tcpip?

在未集成 Google 移动广告的情况下在 Android 上使用 Google 广告 ID

ACR38 阅读器和 SLE4442 Java 延迟