java auth_error ai_generated true

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

ID: java/ssl-peer-unverified

Also available as: JSON · Markdown · 中文
85%Fix Rate
88%Confidence
1Evidence
2023-11-15First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
Java 8 active
Java 11 active
Java 17 active
Java 21 active

Root Cause

The SSL/TLS handshake completed, but the peer's certificate chain could not be verified against the truststore, meaning the server's identity is not trusted.

generic

中文

SSL/TLS 握手已完成,但无法根据信任库验证对端的证书链,意味着服务器身份不受信任。

Official Documentation

https://docs.oracle.com/javase/8/docs/api/javax/net/ssl/SSLPeerUnverifiedException.html

Workarounds

  1. 90% success Import the server's certificate into the JVM's truststore using keytool: `keytool -import -alias server -keystore $JAVA_HOME/lib/security/cacerts -file server.crt`
    Import the server's certificate into the JVM's truststore using keytool: `keytool -import -alias server -keystore $JAVA_HOME/lib/security/cacerts -file server.crt`
  2. 85% success Set the truststore to a custom file containing the server's CA certificate: `-Djavax.net.ssl.trustStore=/path/to/truststore.jks -Djavax.net.ssl.trustStorePassword=changeit`
    Set the truststore to a custom file containing the server's CA certificate: `-Djavax.net.ssl.trustStore=/path/to/truststore.jks -Djavax.net.ssl.trustStorePassword=changeit`
  3. 80% success If using a client library (e.g., OkHttp), configure the client to use a custom SSLSocketFactory that trusts the specific certificate.
    If using a client library (e.g., OkHttp), configure the client to use a custom SSLSocketFactory that trusts the specific certificate.

中文步骤

  1. 使用 keytool 将服务器证书导入 JVM 的信任库:`keytool -import -alias server -keystore $JAVA_HOME/lib/security/cacerts -file server.crt`
  2. 将信任库设置为包含服务器 CA 证书的自定义文件:`-Djavax.net.ssl.trustStore=/path/to/truststore.jks -Djavax.net.ssl.trustStorePassword=changeit`
  3. 如果使用客户端库(例如 OkHttp),配置客户端使用信任特定证书的自定义 SSLSocketFactory。

Dead Ends

Common approaches that don't work:

  1. Set `-Djavax.net.ssl.trustStore` to a non-existent file to bypass trust validation. 90% fail

    This causes a different SSL error: 'java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty', not fixing the peer verification.

  2. Disable SSL verification entirely by setting `HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true)`. 80% fail

    This only bypasses hostname verification; the peer certificate chain is still validated against the truststore, so the error persists.

  3. Use a self-signed certificate but ignore all trust issues by creating a custom TrustManager that trusts all. 60% fail

    While this works for development, it's a security risk and may violate organizational policies; also, some libraries like Apache HttpClient require explicit configuration.