带有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有关,因为它是一个内部包,所以通常不会使用它.激活调试选项可能会激活此内部包?
解决方法:
我今天遇到了同样的问题,我深入研究了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,以便提供者始终寻找正确的值.
标签:smartcard,pkcs11,java,keytool 来源: https://codeday.me/bug/20190926/1817982.html