3

背景信息这可能有助于 alaysis :

我正在尝试从 Web 应用程序连接到智能卡并从运行在客户端计算机上的 java 程序读取证书以执行一些签名操作。我正在使用 Opensc-PKCS11.dll 和 java sunpkcs11 提供程序类来访问智能卡上的证书(FIPS PIV 合规智能卡)。

我的问题是只要连接了智能卡,我就可以访问智能卡上的密钥库并执行加密操作,但是当我们移除智能卡并再次插入时,程序无法获取插槽 ID,因为加载提供程序失败。

由于我无法硬编码我的插槽 ID,因此我将其保留为 0/-1

Config file content
Name="Opensc"
Library="OpenSC-PKCS11.dll"
slot=-1
showinfo=true

byte[] pkcs11configBytes = configName.getBytes();
ByteArrayInputStream confStream = new  ByteArrayInputStream(pkcs11configBytes);
bc = new org.bouncycastle.jce.provider.BouncyCastleProvider();
Security.addProvider(bc);
sun = new sun.security.pkcs11.SunPKCS11(confStream);
Security.addProvider(sun);

尽管相关,但这个问题确实提供了足够的信息。 Java - 如何检测智能卡热插拔

更新:我可以解决这个问题。在 finally 块中,我在提供者的工作完成后从提供者调用了 C_Finalize。对于在同一个 java 实例中的下一次运行,我做了一些类似下面清除 PKCS11 映射并再次初始化提供程序的事情

Field moduleMapField = PKCS11.class.getDeclaredField("moduleMap");  
moduleMapField.setAccessible(true);  
Map<?, ?> moduleMap = (Map<?, ?>) moduleMapField.get(null);  
moduleMap.clear(); // force re-execution of C_Initialize next time  

    //load PKCS#11  
Method getInstanceMethod = PKCS11.class.getMethod("getInstance",  
String.class, String.class, CK_C_INITIALIZE_ARGS.class,  
 Boolean.TYPE);  
CK_C_INITIALIZE_ARGS ck_c_initialize_args = new CK_C_INITIALIZE_ARGS();  
pkcs11 = (PKCS11) getInstanceMethod.invoke(null, libFile,  
  "C_GetFunctionList", ck_c_initialize_args, false);
4

0 回答 0