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 提供程序的操作似乎非常不同:
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
- 在Java9中,自动生成一个SunPKCS11提供者,并在加密提供者列表中。它可以从列表中获取并配置。问题是您只能在列表中加载一个 PKCS#11 提供程序。 Java 9 documentation 表示我们可以使用 "SunPKCS11-" 后跟我们在配置中指定的名称来获取 PKCS#11 提供程序,但事实并非如此。如果我们查看供应商列表,唯一的供应商是 "SunPKCS11",所以我不能每张智能卡有一个供应商。
这是否也发生在其他人身上?有什么解决办法吗?
我注意到正在查看 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 和列表索引的提供程序和不同的属性。
最多 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 提供程序的操作似乎非常不同:
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
- 在Java9中,自动生成一个SunPKCS11提供者,并在加密提供者列表中。它可以从列表中获取并配置。问题是您只能在列表中加载一个 PKCS#11 提供程序。 Java 9 documentation 表示我们可以使用 "SunPKCS11-" 后跟我们在配置中指定的名称来获取 PKCS#11 提供程序,但事实并非如此。如果我们查看供应商列表,唯一的供应商是 "SunPKCS11",所以我不能每张智能卡有一个供应商。
这是否也发生在其他人身上?有什么解决办法吗?
我注意到正在查看 configure
:
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 和列表索引的提供程序和不同的属性。