本文介绍如何排查和修复多线程应用程序访问智能卡时发生的“0x6 ERROR_INVALID_HANDLE”错误。
*适用于:*Windows 10
现象
假设出现了下面这种情景:
- 你拥有一个支持智能卡的多线程应用程序。
- 应用程序正在访问基于 Microsoft 基智能卡加密服务提供程序(basecsp.dll/scksp.dll)的智能卡。
- 应用程序运行一段时间。
在此方案中,您会收到0x6 ERROR_INVALID_HANDLE错误。
如果调用使用事务管理器的任何 Crypto API(例如 CryptGetKeyParam() 和 CryptGetUserKey()),且在释放上下文的另一个调用之前进行,则会出现此问题。
ERROR_INVALID_HANDLE错误不会立即出现。 根据负载,线程遇到同步问题需要时间。
原因
之所以会出现此问题,是因为 BaseCSP 不是针对高负载方案设计的。 因此,BaseCSP 智能卡既不是线程安全,也不在高负载方案中受支持。
详细信息
BaseCSP 只能在典型使用方案中实现线程安全性,例如单用户、智能卡登录、电子邮件加密或解密以及代码签名。
在典型的使用方案中,BaseCSP 应为每个上下文提供线程安全。 在高负载方案中,BaseCSP 智能卡遇到事务管理器同步问题。
解决方法
若要解决此问题,请使用以下方法之一。
方法 1
开发供应商 CSP 或 KSP 提供程序,并在其中实现事务管理器。 通过这种方式,智能卡子系统不会使用在 BaseCSP 中实现的事务管理器。
方法 2
重要
请认真遵循本部分所述的步骤。 如果注册表修改不正确,可能会发生严重问题。 在修改注册表之前,请备份注册表,以便在出现问题时可以还原。
较短的事务超时时间可以减少问题发生的频率。 为此,请启动 regedit,并在 TransactionTimeoutMilliseconds 的子项下更改 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Defaults\Provider\<provider_name> 值。
注意
在此子项中, <provider_name> 是 BaseCSP 或 ksp,具体取决于提供程序。
有关详细的注册表说明,请参阅 基本 CSP 和智能卡 KSP 注册表项。
例如,将 TransactionTimeoutMilliseconds 从默认值 1500 毫秒减少到 100 毫秒可能会降低问题的频率。
重要
此更改只是基于有限测试结果的建议。 不能保证减少 TransactionTimeoutMilliseconds 值将有助于控制此问题。 此外,更改 TransactionTimeoutMilliseconds** 的**默认值可能会导致其他问题影响 BaseCSP 卡。 在部署此更改之前,请确保对相关应用程序和负载彻底测试卡片。