带有 opensc pkcs#11 提供程序的 java keytool 仅适用于启用调试选项的情况
我在 ubuntu 11.10 上使用 OpenJDK (java 版本“1.6.0_22”)运行最新的 opensc 0.12.2
我可以使用以下命令读取我的智能卡(飞天 ePass PKI)
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
通常可能不会使用,因为它是内部包。激活调试选项可能会激活这个内部包?
I have the latest opensc 0.12.2 running on ubuntu 11.10 with OpenJDK ( java version "1.6.0_22")
I can read my smartcard (a Feitian ePass PKI) with
pkcs15-tool --dump
Now i try to use my smartcard with keytool:
keytool
-providerClass sun.security.pkcs11.SunPKCS11 \
-providerArg /etc/opensc/opensc-java.cfg \
-keystore NONE -storetype PKCS11 -list
which results in an error:
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
When i run the same command with debug options enabled like this:
keytool
-providerClass sun.security.pkcs11.SunPKCS11 \
-providerArg /etc/opensc/opensc-java.cfg \
-keystore NONE -storetype PKCS11 -list \
-J-Djava.security.debug=sunpkcs11
it suddenly works:
... 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): ...
The same behaviour when i configure it statically:
$ 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
and my config
$ cat /etc/opensc/opensc-java.cfg
name = OpenSC
description = SunPKCS11 w/ OpenSC Smart card Framework
library = /usr/lib/opensc-pkcs11.so
My guess it, it has something to do with openjdk or internal package sun.security
which might usually not be used because it is an internal package. Activating Debug options might activate this internal package?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我今天遇到了同样的问题,我深入研究了java源代码,直到找到问题的根源。我知道这个问题已经很老了并且已经有一个公认的答案,但那不是真正的答案。
基本上,SunPKCS11 提供程序会列出所有可用的插槽,然后获取您在配置中指定的插槽,并给出错误(因为您没有指定任何插槽并使用其默认值)。
在调试时,在列出所有可用插槽后,它会列出插入了智能卡的所有插槽。打印有关插槽列表的所有这些信息后,它会初始化其 slotid 变量,覆盖您在配置中写入(或忘记写入)的内容。新值是正确的,因为它是从 opensc 默认值读取的。
这是来自 openjdk 项目的 SunPKCS11.java 的相关代码:
因此,解决方法是始终在配置中包含负值,例如
slot = -1
,以便提供程序始终寻找正确的值一。I got the same problem today and I digged onto the java sources until I found the source of the problem. I know this question is quite old and already have an accepted answer, but that one is not a real answer.
Basically, the SunPKCS11 provider does list all available slots, then, get the slot you specified in your config, and give the error (since you do not specified any slot and fot its default value).
When in debug, after listing all available slots, it does list all slots with a smartcard inserted. After having print all these information about the slot list, it does initialise its slotid variable overwriting what you wrote (or forget to write) in your config. The new value is a correct one since it is read from the opensc defaults.
This is the relevant code from SunPKCS11.java from openjdk project:
So, a workaround is to always include in your config a negative value like
slot = -1
, so that the provider will always look for the right one.将调试标志添加到命令行对我有用:
或者手动指定 cfg 文件中的插槽:
Adding the debug flag to the command line worked for me:
Or manually specifying the slot in the cfg file:
我可以使用 java JDK 1.6.0_20 确认此行为,
即使是一个简单的 java 程序也仅适用于 -Djava.security.debug=sunpkcs11 设置。
与 /etc/pkcs11_java.cfg
I can confirm this behavior using java JDK 1.6.0_20
Even a simple java program only works with -Djava.security.debug=sunpkcs11 set.
with /etc/pkcs11_java.cfg