简体   繁体   English

通过 JLink 创建的 JRE 缺少一些安全证书 (cacerts)

[英]JRE created via JLink missing some security certificates (cacerts)

I've created a minified JRE using the JLink tool我使用 JLink 工具创建了一个缩小的 JRE

jlink --add-modules java.base,jdk.crypto.ec --output jre

I've created a very basic application that connects to https://www.example.com我创建了一个连接到https://www.example.com的非常基本的应用程序

When I run this application using the JDK, everything works fine.当我使用 JDK 运行此应用程序时,一切正常。 When I run this using the minified JRE, I get the following:当我使用缩小的 JRE 运行它时,我得到以下信息:

Exception in thread "main" javax.net.ssl.SSLException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
        at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:133)
        at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:320)
        at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:263)
        at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:258)
        at java.base/sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1313)
        at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:408)
        at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:567)
        at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
        at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1587)
        at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1515)
        at java.base/java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:527)
        at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:334)
        at URLTest.printResponseCode(URLTest.java:68)
        at URLTest.main(URLTest.java:47)
Caused by: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
        at java.base/sun.security.validator.PKIXValidator.<init>(PKIXValidator.java:102)
        at java.base/sun.security.validator.Validator.getInstance(Validator.java:181)
        at java.base/sun.security.ssl.X509TrustManagerImpl.getValidator(X509TrustManagerImpl.java:300)
        at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrustedInit(X509TrustManagerImpl.java:176)
        at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:189)
        at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:129)
        at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1316)
        at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.onConsumeCertificate(CertificateMessage.java:1207)
        at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.consume(CertificateMessage.java:1150)
        at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
        at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:443)
        at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:421)
        at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:177)
        at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:164)
        at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1151)
        at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1062)
        at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:402)
        ... 8 more
Caused by: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
        at java.base/java.security.cert.PKIXParameters.setTrustAnchors(PKIXParameters.java:200)
        at java.base/java.security.cert.PKIXParameters.<init>(PKIXParameters.java:120)
        at java.base/java.security.cert.PKIXBuilderParameters.<init>(PKIXBuilderParameters.java:104)
        at java.base/sun.security.validator.PKIXValidator.<init>(PKIXValidator.java:99)
        ... 24 more

I've noticed the lib\\security\\cacerts file in the JDK is much larger than in the minified JRE (246KB vs 156KB).我注意到 JDK 中的lib\\security\\cacerts文件比缩小的 JRE(246KB vs 156KB)大得多。 When I copy this file into the minified JRE, then my application works correctly.当我将此文件复制到缩小的 JRE 中时,我的应用程序可以正常工作。

This suggests that the JLink process is removing some of the certificates for some reason.这表明 JLink 进程出于某种原因正在删除某些证书。 I can't see any explanation in the documentation for this, or online.我在文档或在线看不到任何解释。 Am I missing something?我错过了什么吗?

Having seen this on OpenJDK, I don't think it is a Corretto only bug.在 OpenJDK 上看到这个后,我认为这不是 Corretto 唯一的错误。 I think the Corretto bug was just that some AWS certs were added to the regular JDK cacerts file but not the cacerts file in the jlink base mod.我认为 Corretto 错误只是将一些 AWS 证书添加到常规 JDK​​ cacerts 文件中,而不是 jlink base mod 中的 cacerts 文件。

We experienced the same issue when trying to add some new ca certs using keytool, only the lib/security/cacerts file in the JDK was updated and not the one that is inside jmods/java.base.jmod which is where the cacerts file is sourced from when using jlink.我们在尝试使用 keytool 添加一些新的 ca 证书时遇到了同样的问题,仅更新了 JDK 中的 lib/security/cacerts 文件,而不是 jmods/java.base.jmod 中的文件,即 cacerts 文件所在的位置来自使用 jlink 时。

The solution was to update lib/security/cacerts inside of jmods/java.base.jmod before running jlink.解决方案是在运行 jlink 之前更新 jmods/java.base.jmod 中的 lib/security/cacerts。 The .jmod file format is zip with an extra header at the beginning of the zip which is 4 bytes. .jmod 文件格式是 zip,在 zip 的开头有一个额外的标头,它是 4 个字节。 The header consists of the initials "JM" followed by the jmod major version number 0x01 and the jmod minor version number 0x00.标头由首字母“JM”后跟 jmod 主要版本号 0x01 和 jmod 次要版本号 0x00 组成。 If you are interested, more at https://hg.openjdk.java.net/jdk9/jdk9/jdk/file/tip/src/java.base/share/classes/jdk/internal/jmod/JmodFile.java and https://bugs.astron.com/view.php?id=59如果您有兴趣,请访问https://hg.openjdk.java.net/jdk9/jdk9/jdk/file/tip/src/java.base/share/classes/jdk/internal/jmod/JmodFile.javahttps ://bugs.astron.com/view.php?id=59

Our fix on Linux was to run the following from the JDK dir:我们在 Linux 上的修复是从 JDK 目录运行以下内容:

tail -c +5 jmods/java.base.jmod > jmods/java.base.jmod.zip
zip -ur jmods/java.base.jmod.zip lib/security/cacerts
printf "\x4a\x4d\x01\x00" | cat - jmods/java.base.jmod.zip > jmods/java.base.jmod
rm jmods/java.base.jmod.zip

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将wsdl证书集成到jdk / jre / security文件夹中的cacerts文件中? - How to integrate wsdl certificates to the cacerts file in jdk/jre/security folder? 如何将SSL证书集成到/ jre / security文件夹中的cacerts文件? - How to integrate SSL certificates to the cacerts file in /jre/security folder? jre \\ lib \\ security \\ cacerts不是合法命令 - jre\lib\security\cacerts is not a legal command 我们可以从 JRE 的“cacerts”文件中导出证书并将其导入更高的 JRE 版本吗? - Can we export certificates from JRE's "cacerts" file and import it to higher JRE version? cacerts - JDK或JRE - cacerts - JDK or JRE 使用 JLink JRE 的 Spring Boot - Spring Boot with JLink JRE 有没有办法加载不同于java_home / jre / lib / security文件夹中指定的cacerts? - Is there a way to load a different cacerts than the one specified in the java_home/jre/lib/security folder? java 9:JLink创建了无效图像 - 缺少模块可执行脚本 - java 9: JLink created invalid images - missing module executable script Android Studio错误:/ usr / lib / jvm / java-7-openjdk-amd64 / jre / lib / security / cacerts(无此类文件或目录) - Android Studio Error:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/security/cacerts (No such file or directory) 使用 jlink 创建运行时的 SSLHandshakeException - SSLHandshakeException with jlink created runtime
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM