带有opensc pkcs#11提供程序的智能卡java密钥工具仅在启用调试选项的情况下工作
我有最新的OpenSC0.12.2运行在Ubuntu11.10和OpenJDK上(java版本“1.6.0_22”)
我可以用
pkcs15-tool --dump
现在我尝试将我的智能卡与keytool一起使用:
keytool
-providerClass sun.security.pkcs11.SunPKCS11 \
-providerArg /etc/opensc/opensc-java.cfg \
-keystore NONE -storetype PKCS11 -list
这会导致错误:
keytool error: java.security.KeyStoreException: PKCS11 not found
java.security.KeyStoreException: PKCS11 not found
at java.security.KeyStore.getInstance(KeyStore.java:603)
at sun.security.tools.KeyTool.doCommands(KeyTool.java:621)
at sun.security.tools.KeyTool.run(KeyTool.java:194)
at sun.security.tools.KeyTool.main(KeyTool.java:188)
Caused by: java.security.NoSuchAlgorithmException: PKCS11 KeyStore not available
at sun.security.jca.GetInstance.getInstance(GetInstance.java:159)
at java.security.Security.getImpl(Security.java:696)
at java.security.KeyStore.getInstance(KeyStore.java:600)
... 3 more
当我在启用调试选项的情况下运行相同的命令时,如下所示:
keytool
-providerClass sun.security.pkcs11.SunPKCS11 \
-providerArg /etc/opensc/opensc-java.cfg \
-keystore NONE -storetype PKCS11 -list \
-J-Djava.security.debug=sunpkcs11
它突然起作用了:
... debug infos ...
Enter keystore password:
sunpkcs11: login succeeded
Keystore type: PKCS11
Keystore provider: SunPKCS11-OpenSC
Your keystore contains 2 entries
...
Certificate fingerprint (MD5): ...
...
Certificate fingerprint (MD5): ...
静态配置时的相同行为:
$ grep opensc /usr/lib/jvm/java-6-openjdk/jre/lib/security/java.security
security.provider.7=sun.security.pkcs11.SunPKCS11 /etc/opensc/opensc-java.cfg
还有我的配置
$ cat /etc/opensc/opensc-java.cfg
name = OpenSC
description = SunPKCS11 w/ OpenSC Smart card Framework
library = /usr/lib/opensc-pkcs11.so
我猜它与openjdk或内部包sun.security
有关,因为它是一个内部包,所以通常不会使用。激活调试选项可能会激活此内部包
# 1 楼答案
今天我遇到了同样的问题,我深入研究了java源代码,直到找到了问题的根源。我知道这个问题已经很老了,已经有了一个公认的答案,但那不是一个真正的答案
基本上,SunPKCS11提供程序会列出所有可用的插槽,然后获取您在配置中指定的插槽,并给出错误信息(因为您没有指定任何插槽,并将其设置为默认值)
在调试中,列出所有可用插槽后,它会列出插入智能卡的所有插槽。打印完所有关于插槽列表的信息后,会初始化其slotid变量,覆盖您在配置中写入的内容(或忘记写入)。新值是正确的,因为它是从opensc默认值读取的
这是来自SunPKCS11的相关代码。来自openjdk项目的java:
因此,一种解决方法是在配置中始终包含一个负值,如
slot = -1
,以便提供程序始终查找正确的值# 2 楼答案
将调试标志添加到命令行对我有效:
或手动指定cfg文件中的插槽:
# 3 楼答案
我可以使用JavaJDK1.6.0\u20确认这种行为
即使是一个简单的java程序也只能与-Djava一起工作。安全调试=设置sunpkcs11
使用/etc/pkcs11_java。cfg