javax.net.ssl.SSLPeerUnverifiedException:对端未认证
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
ID: java/ssl-peer-unverified
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| Java 8 | active | — | — | — |
| Java 11 | active | — | — | — |
| Java 17 | active | — | — | — |
| Java 21 | active | — | — | — |
根因分析
SSL/TLS 握手已完成,但无法根据信任库验证对端的证书链,意味着服务器身份不受信任。
English
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.
官方文档
https://docs.oracle.com/javase/8/docs/api/javax/net/ssl/SSLPeerUnverifiedException.html解决方案
-
使用 keytool 将服务器证书导入 JVM 的信任库:`keytool -import -alias server -keystore $JAVA_HOME/lib/security/cacerts -file server.crt`
-
将信任库设置为包含服务器 CA 证书的自定义文件:`-Djavax.net.ssl.trustStore=/path/to/truststore.jks -Djavax.net.ssl.trustStorePassword=changeit`
-
如果使用客户端库(例如 OkHttp),配置客户端使用信任特定证书的自定义 SSLSocketFactory。
无效尝试
常见但无效的做法:
-
Set `-Djavax.net.ssl.trustStore` to a non-existent file to bypass trust validation.
90% 失败
This causes a different SSL error: 'java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty', not fixing the peer verification.
-
Disable SSL verification entirely by setting `HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true)`.
80% 失败
This only bypasses hostname verification; the peer certificate chain is still validated against the truststore, so the error persists.
-
Use a self-signed certificate but ignore all trust issues by creating a custom TrustManager that trusts all.
60% 失败
While this works for development, it's a security risk and may violate organizational policies; also, some libraries like Apache HttpClient require explicit configuration.