带有opensc pkcs#11提供程序的java keytool仅在启用调试选项的情况下工作 [英] java keytool with opensc pkcs#11 provider only works with debug option enabled

查看:222
本文介绍了带有opensc pkcs#11提供程序的java keytool仅在启用调试选项的情况下工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用OpenJDK的ubuntu 11.10上运行了最新的opensc 0.12.2(java版本为"1.6.0_22")

I have the latest opensc 0.12.2 running on ubuntu 11.10 with OpenJDK ( java version "1.6.0_22")

我可以通过以下方式读取我的智能卡(Feitian ePass PKI)

I can read my smartcard (a Feitian ePass PKI) with

pkcs15-tool --dump

现在我尝试将我的智能卡与keytool一起使用:

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 

这会导致错误:

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

它突然起作用:

... 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

和我的配置

$ cat /etc/opensc/opensc-java.cfg
name = OpenSC
description = SunPKCS11 w/ OpenSC Smart card Framework
library = /usr/lib/opensc-pkcs11.so

我猜想,这与openjdk或内部软件包sun.security有关,它们通常不使用,因为它是内部软件包.激活调试选项可能会激活此内部程序包吗?

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?

推荐答案

我今天遇到了同样的问题,并且挖掘了Java源代码,直到找到问题的根源.我知道这个问题已经很老了,已经有了一个可以接受的答案,但是那不是一个真正的答案.

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.

基本上,SunPKCS11提供程序会列出所有可用的插槽,然后,获取您在配置中指定的插槽,并给出错误信息(因为您未指定任何插槽,并且未指定其默认值).

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).

在调试时,列出所有可用插槽后,它会列出所有插入了智能卡的插槽.在打印完有关插槽列表的所有这些信息之后,它会初始化其slotid变量,从而覆盖您在配置中写入(或忘记写入)的内容.新值是正确的值,因为它是从opensc默认值中读取的.

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.

这是来自openjdk项目的SunPKCS11.java的相关代码:

This is the relevant code from SunPKCS11.java from openjdk project:

    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,以便提供程序始终寻找正确的值.

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.

这篇关于带有opensc pkcs#11提供程序的java keytool仅在启用调试选项的情况下工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆