Java 9中的SunPKCS11提供程序
在Java 8之前,SunPKCS11提供程序的加载方式如下:
Provider provider = new sun.security.pkcs11.SunPKCS11 (new ByteArrayInputStream (configFile.getBytes ())); Security.addProvider (provider);
configFile
是一个带有配置参数的String。 因此,如果应用程序需要使用多个连接的智能卡,它可以创建多个提供程序。 要访问每个提供程序,使用的名称是“SunPKCS11-”,后跟我们在配置中指示的名称。
在Java 8中,在JDK中删除了sun.security.pkcs11.SunPKCS11
类。 所以,我不得不通过反思来编程前一个调用。
Java 9中PKCS#11提供程序的操作看起来非常不同:
-
SunPKCS11
构造函数已更改为空构造函数。 配置由“configure”方法加载,因此必须将它放在磁盘上的文件中,我不能再通过流将其加载到字符串。 -
如果我们尝试使用reflection,则会出现以下警告:
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文档表明我们可以通过“SunPKCS11-”获取PKCS#11提供程序,后跟我们在配置中指示的名称,但事实并非如此。 如果我们查看提供商列表,唯一的一个是“SunPKCS11”,因此我不能为每个智能卡提供一个提供商。
这也发生在其他人身上吗? 有解决方案吗
我注意到查看configure
的javadoc:
将提供的配置参数应用于此提供程序实例,并返回配置的提供程序。 请注意,如果无法就地配置此提供程序,则将创建并返回新的提供程序 。 因此,调用者应始终使用返回的提供者。
这向我表明原型模式在这里被使用,并且用于创建多个提供者的新控制流将类似于:
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
的参数。 所以你应该能够将配置参数作为字符串传递,只要你用--
启动字符串,然后用\n
分隔你的key=value
对。 (我现在无法测试这个)。
但是,我无法在任何地方公开记录这一事实,因此它可能会发生变化,并且对不同的提供商有不同的工作方式,即使用风险自负! 。
问题是您只能在列表中加载一个PKCS#11提供程序。
你问题的解决方案似乎是在doc链接本身中定义的。
要为每个PKCS#11
实现使用多个插槽,或使用多个PKCS#11
实现,只需使用相应的配置文件为每个插槽重复安装。 这将为每个PKCS#11
实现的每个插槽生成一个Sun PKCS#11提供程序实例 。
格式attribute=value
示例配置将是:
name = FooAccelerator library = /opt/foo/lib/libpkcs11.so slot = 1
您可以在同一链接中的PKCS#11提供程序配置文件中进一步使用属性来配置具有不同插槽ID和listIndex以及不同属性的多个提供程序。