Java 9中的SunPKCS11提供程序


问题内容

在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该类已在JDK中删除。因此,我必须通过反射对上一个调用进行编程。

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

  • SunPKCS11构造已更改为空单。配置是通过“ configure”方法加载的,因此必须将其保存在磁盘上的文件中,并且我无法再通过流将其加载到字符串中。

  • 如果我们尝试使用反射,则会出现以下警告:

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

  • 在Java 9中,将自动生成SunPKCS11提供程序,该程序位于加密提供程序的列表中。可以从列表中获取并进行配置。问题是您只能在列表中加载一个PKCS#11提供程序。在Java的9文档表明,我们可以得到的PKCS#11提供商,“SunPKCS11-”之后,我们在配置中指示的名字,但事实并非如此。如果我们查看提供商列表,则只有一个是“ SunPKCS11”,因此每个智能卡都不能有一个提供商。

别人也会这样吗?有什么办法吗?


问题答案:

我注意到在看javadoc
configure

将提供的配置参数应用于此提供程序实例,然后返回配置的提供程序。请注意,如果无法就地配置此提供 程序,则将创建并返回一个新的提供程序
。因此,呼叫者应始终使用返回的提供程序。

这向我表明这里正在使用原型模式,并且用于创建多个提供程序的新控制流将类似于:

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``\n

但是,我在任何地方都找不到公开记录的事实,因此它可能会发生变化,并且对不同的提供者也有不同的作用,即 使用风险自负!