分类: Java开发

SNI 兼容性导致 HTTPS 访问异常

直接贴日志吧,发现有台机器访问 https 就会有以下异常:

javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative DNS name matching wos.58cdn.com.cn found.
        at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1747)
        at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:241)
        at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:235)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1209)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:135)
        at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
        at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:943)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1188)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1215)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1199)
        at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)
        at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
        at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1031)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230)
        ... more
Caused by: java.security.cert.CertificateException: No subject alternative DNS name matching wos.58cdn.com.cn found.
        at sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:193)
        at sun.security.util.HostnameChecker.match(HostnameChecker.java:77)
        at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:264)
        at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:250)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1188)
        ... 39 more

提示域名证书不匹配,其实这个是 SIN 导致的,先大体说一下 SNI 是什么。

随着 IPv4 地址的短缺,为了让多个域名复用一个 IP 地址,在 HTTP 服务器上引入了虚拟主机的概念。服务器可以根据客户端请求中不同的 Host,将请求分配给不同的域名(虚拟主机)来处理。在一个被多个域名(虚拟主机)共享 IP 的 HTTPS 服务器中,当浏览器访问一个 HTTPS 站点时,会首先与服务器建立 SSL 连接。建立 SSL 连接的第一步是请求服务器的证书。服务器在发送证书时,不知道浏览器访问的是哪个域名,所以不能根据不同域名发送不同的证书。

SNI(Server Name Indication)是为了解决一个服务器使用多个域名和证书的 SSL/TLS 扩展。它的工作原理是:在连接到服务器建立 SSL 连接之前,先发送要访问站点的域名(Hostname),这样服务器会根据这个域名返回一个合适的证书。

目前,大多数操作系统和浏览器都已经很好地支持 SNI 扩展。JDK 也在版本 1.7 中支持了这一特性,但恰好这台服务器就是 1.6 的。

至此解决方案也出来了,只需要把 jdk 版本升一下级就可以了。

Recent Posts

Docker 容器非 root 用户监听 80 端口

起因是基于 CentOS 的 …

2 年 之前

基于 Docker 定时打印文件

先说背景,喷墨打印机有个很大的…

3 年 之前

Java 运行时反射获取来自继承的泛型

背景 正常情况下 Java 的…

3 年 之前

Java 基于 ByteBuddy 重写系统当前时间

背景 一般单元测试时总会有些代…

3 年 之前

华硕 B450F-Gaming 主板 I211-AT 网卡驱动安装

事情起因是买了块华硕的 ROG…

3 年 之前

PHP 安装 Memcached 扩展

登录服务器挨步执行: # su…

4 年 之前