簡體   English   中英

通過 JLink 創建的 JRE 缺少一些安全證書 (cacerts)

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

我使用 JLink 工具創建了一個縮小的 JRE

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

我創建了一個連接到https://www.example.com的非常基本的應用程序

當我使用 JDK 運行此應用程序時,一切正常。 當我使用縮小的 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

我注意到 JDK 中的lib\\security\\cacerts文件比縮小的 JRE(246KB vs 156KB)大得多。 當我將此文件復制到縮小的 JRE 中時,我的應用程序可以正常工作。

這表明 JLink 進程出於某種原因正在刪除某些證書。 我在文檔或在線看不到任何解釋。 我錯過了什么嗎?

在 OpenJDK 上看到這個后,我認為這不是 Corretto 唯一的錯誤。 我認為 Corretto 錯誤只是將一些 AWS 證書添加到常規 JDK​​ cacerts 文件中,而不是 jlink base mod 中的 cacerts 文件。

我們在嘗試使用 keytool 添加一些新的 ca 證書時遇到了同樣的問題,僅更新了 JDK 中的 lib/security/cacerts 文件,而不是 jmods/java.base.jmod 中的文件,即 cacerts 文件所在的位置來自使用 jlink 時。

解決方案是在運行 jlink 之前更新 jmods/java.base.jmod 中的 lib/security/cacerts。 .jmod 文件格式是 zip,在 zip 的開頭有一個額外的標頭,它是 4 個字節。 標頭由首字母“JM”后跟 jmod 主要版本號 0x01 和 jmod 次要版本號 0x00 組成。 如果您有興趣,請訪問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

我們在 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM