Java 9 中的 SunPKCS11 提供程序

SunPKCS11 provider in Java 9

最多 Java 8 SunPKCS11 提供程序是这样加载的:

Provider provider = new sun.security.pkcs11.SunPKCS11 (new ByteArrayInputStream (configFile.getBytes ()));
Security.addProvider (provider);

configFile 是一个带有配置参数的字符串。因此,如果应用程序需要使用多个连接的智能卡,它可以创建多个提供程序。要访问每个提供程序,使用的名称是 "SunPKCS11-" 后跟我们在配置中指定的名称。

在 Java 8 中,sun.security.pkcs11.SunPKCS11 class 在 JDK 中被删除。所以,我不得不通过反射对之前的调用进行编程。

Java9 中 PKCS#11 提供程序的操作似乎非常不同:

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by PruebaTarjeta (file:/C:/temp/pkcs11java9/classes/) to constructor
sun.security.pkcs11.SunPKCS11()
WARNING: Please consider reporting this to the maintainers of PruebaTarjeta
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

这是否也发生在其他人身上?有什么解决办法吗?

我注意到正在查看 configure:

的 javadoc

Apply the supplied configuration argument to this provider instance and return the configured provider. Note that if this provider cannot be configured in-place, a new provider will be created and returned. Therefore, callers should always use the returned provider.

这向我表明这里正在使用 prototype pattern,并且用于创建多个提供者的新控制流类似于:

Provider prototype = Security.getProvider("SunPKCS11");
Provider provider1 = prototype.configure(...);
Provider provider2 = prototype.configure(...);
...

至于直接使用参数而不是文件名,我深入研究了源代码并在 sun.security.pkcs11.Config:

中找到了这个
Config(String fn) throws IOException {
    this.filename = fn;
    if (filename.startsWith("--")) {
        // inline config
        String config = filename.substring(2).replace("\n", "\n");
        reader = new StringReader(config);

注意带有 filename.startsWith("--") 的行,此文件名直接来自 configure 的参数。所以你 应该 能够将配置参数作为字符串传递,只要你以 -- 开始字符串,然后用 key=value 分隔你的 key=value 对=18=]。 (虽然我目前无法对此进行测试)。

但是,我无法在任何地方找到公开记录的这一事实,因此它可能会发生变化,并且它对不同的提供商有不同的工作方式,即 自己使用风险!.

The problem is that you can only have one PKCS#11 provider loaded in the list.

您的问题的解决方案似乎在 doc linked itself.

中定义

要在每个 PKCS#11 实施中使用多个插槽,或使用多个 PKCS#11 实施,只需使用适当的配置文件为每个重复安装即可。此 将为每个 PKCS#11 实现的每个插槽生成一个 Sun PKCS#11 提供程序实例。

遵循格式 attribute=value 的示例配置为:

name = FooAccelerator
library = /opt/foo/lib/libpkcs11.so
slot = 1

您可以进一步利用 PKCS#11 提供程序配置文件中的 属性 在同一个 link 中配置多个具有不同插槽 ID 和列表索引的提供程序和不同的属性。