从OpenJDK16读取使用keytool创建的PKCS12密钥库时Java8中的IOException

TL; 博士

keytool从 OpenJDK16 创建的 PKCS12 密钥库文件无法从 Java 8、9、10 和 11 中读取。这是错误吗?如何创建适用于 Java 8 的 PKCS12 密钥库?

语境

我构建了一个 Maven 项目,该项目生成一个可执行 JAR 文件,该文件必须在从版本 8 到版本 16 的任何 JRE 上运行。该 JAR 文件生成一个 HTTPS 服务器(使用com.sun.net.httpserver.HttpsServer)。

在构建期间,我使用keytool生成密钥对并将其存储在捆绑在 JAR 中的 PKCS12 密钥库中(实际上,我使用的是keytool-maven-plugin):

$ /path/to/jdk16/bin/keytool -genkeypair -keystore /tmp/keystore.p12 -storepass password -storetype PKCS12 -alias https -dname "CN=localhost, OU=My HTTP Server, O=Sentry Software, C=FR" -keypass password -validity 3650 -keyalg RSA -sigalg SHA256withRSA

Java 代码使用这个自动生成的密钥库来启动 HTTPS 服务器:

// initialize the HTTPS server
httpsServer = HttpsServer.create(socketAddress, 0);

// initialize the keystore
KeyStore keyStore = KeyStore.getInstance("PKCS12");

// Load the self-certificate that is bundled with the JAR (see pom.xml)
InputStream ksStream = this.getClass().getResourceAsStream("/keystore.p12");
keyStore.load(ksStream, "password".toCharArray()); // Exception here

// Rest of the code (only for context purpose)

// setup the key manager factory
String defaultKeyManagerAlgorithm = KeyManagerFactory.getDefaultAlgorithm();
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(defaultKeyManagerAlgorithm);
keyManagerFactory.init(keyStore, "password".toCharArray());

// setup the trust manager factory
String defaultTrustManagerAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(defaultTrustManagerAlgorithm);
trustManagerFactory.init(keyStore);

// setup the HTTPS context and parameters
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);

// Sets the default SSL configuration (no need for extra code here!)
httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext));

问题

当 JAR 使用 OpenJDK 16 JDK 构建(并且keytool使用 OpenJDK 16 中的)然后在 Java 8 JRE 中执行时,我们会收到以下异常keyStore.load()

IOException: parseAlgParameters failed: ObjectIdentifier() -- data isn't an object ID (tag = 48)

在 OpenJDK 11.0.7+10 中执行相同的 JAR 时,我们得到这个异常:

IOException: Integrity check failed: java.security.NoSuchAlgorithmException: Algorithm HmacPBESHA256 not available

但是,当使用 OpenJDK 14、15 或 16 执行相同的 JAR 时,没有例外,一切正常。

下面的表格总结了 的版本keytool,以及每个版本创建的 PKCS12 密钥库是否keytool可以在各种 JRE 版本中加载:

JRE 8 JRE 11 JRE 14 JRE 16
钥匙工具 8 ? ? ? ?
钥匙工具 11 ? ? ? ?
钥匙工具 14 ? ? ? ?
钥匙工具 15 ? ? ? ?
钥匙工具 16 ? ? ? ?
以上是从OpenJDK16读取使用keytool创建的PKCS12密钥库时Java8中的IOException的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>