带有 opensc pkcs#11 提供程序的 java keytool 仅适用于启用调试选项的情况

发布于 2024-12-17 23:13:05 字数 2044 浏览 2 评论 0原文

我在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

浅笑依然 2024-12-24 23:13:05

我今天遇到了同样的问题,我深入研究了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,以便提供程序始终寻找正确的值一。

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:

    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;

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.

云巢 2024-12-24 23:13:05

将调试标志添加到命令行对我有用:

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

Adding the debug flag to the command line worked for me:

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

Or manually specifying the slot in the cfg file:

name = OpenSC
description = SunPKCS11 w/ OpenSC Smart card Framework
library = /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so
slot = 2
梦忆晨望 2024-12-24 23:13:05

我可以使用 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.so

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.

String configName = "/etc/pkcs11_java.cfg";
Provider p = new sun.security.pkcs11.SunPKCS11(configName);
keyStore = KeyStore.getInstance("PKCS11", p);

with /etc/pkcs11_java.cfg

name=OpenSC
description = SunPKCS11 via OpenSC
library=/usr/local/lib/opensc-pkcs11.so
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文