我有最新的opensc 0.12.2运行在ubuntu11.10和OpenJDK ( java版本"1.6.0_22")上。
我可以读取我的智能卡(飞天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有关,因为它是一个内部包,通常不会使用。激活调试选项可能会激活此内部包?
发布于 2013-05-27 23:20:19
我今天也遇到了同样的问题,我深入研究了java源代码,直到我找到了问题的根源。我知道这个问题很古老,而且已经有了公认的答案,但这个答案并不是真正的答案。
基本上,SunPKCS11提供程序会列出所有可用插槽,然后获取您在配置中指定的插槽,并给出错误(因为您没有指定任何插槽,也没有指定其默认值)。
在调试时,在列出所有可用插槽后,它会列出所有插入了智能卡的插槽。打印完所有这些关于插槽列表的信息后,它会初始化slotid变量,覆盖您在配置中写入(或忘记写入)的内容。新值是正确的,因为它是从opensc默认值中读取的。
以下是来自openjdk项目的SunPKCS11.java的相关代码:
long slotID = config.getSlotID();
// ....
if ((slotID < 0) || showInfo) {
long[] slots = p11.C_GetSlotList(false);
if (showInfo) {
System.out.println("All slots: " + toString(slots));
slots = p11.C_GetSlotList(true);
System.out.println("Slots with tokens: " + toString(slots));
}
if (slotID < 0) {
if ((slotListIndex < 0) || (slotListIndex >= slots.length)) {
throw new ProviderException("slotListIndex is " + slotListIndex
+ " but token only has " + slots.length + " slots");
}
slotID = slots[slotListIndex];
}
}
this.slotID = slotID;因此,一种变通办法是在您的配置中始终包含一个负值,如slot = -1,这样提供商将始终查找正确的值。
发布于 2014-01-08 05:47:20
将debug标志添加到命令行对我有效:
keytool -providerClass sun.security.pkcs11.SunPKCS11 \
-providerArg /home/hans/Desktop/smartcards/opensc-java.cfg \
-providerName SunPKCS11-OpenSC -keystore NONE -storetype PKCS11 \
-list \
-J-Djava.security.debug=sunpkcs11或在cfg文件中手动指定插槽:
name = OpenSC
description = SunPKCS11 w/ OpenSC Smart card Framework
library = /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so
slot = 2发布于 2011-12-08 18:02:22
我可以使用java JDK 1.6.0_20来确认这个行为。
即使是一个简单的java程序也只能在设置了-Djava.security.debug=sunpkcs11的情况下运行。
String configName = "/etc/pkcs11_java.cfg";
Provider p = new sun.security.pkcs11.SunPKCS11(configName);
keyStore = KeyStore.getInstance("PKCS11", p);使用/etc/pkcs11_java.cfg
name=OpenSC
description = SunPKCS11 via OpenSC
library=/usr/local/lib/opensc-pkcs11.sohttps://stackoverflow.com/questions/8247115
复制相似问题