SSLHandshakeException: No subject alternative names matching IP address found
阿新 • • 發佈:2019-02-04
一、異常日誌
javax.net.ssl.SSLHandshakeException: Caused by: java.security.cert.CertificateException: No subject alternative names matching IP address 110.75.244.16 found at sun.security.util.HostnameChecker.matchIP(Unknown Source) at sun.security.util.HostnameChecker.match(Unknown Source) at sun.security.ssl.X509TrustManagerImpl.checkIdentity(Unknown Source) at sun.security.ssl.X509TrustManagerImpl.checkIdentity(Unknown Source) at sun.security.ssl.X509TrustManagerImpl.checkTrusted(Unknown Source) at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source) ... 12 more
二、異常程式碼
public class SslHandshakeExc_NsanMatchingIp{ public static void main(String[] args) throws Exception { URL url = new URL("https://110.75.244.16/gateway.do"); // openapi.alipay.com HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); conn.connect(); InputStream is = conn.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String line; while ((line = br.readLine()) != null) { System.out.println(line); } br.close(); is.close(); } }
三、處理方案
public class SslHandshakeExc_NsanMatchingIp{ public static void main(String[] args) throws Exception { URL url = new URL("https://110.75.244.16/gateway.do"); // openapi.alipay.com HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); // 新增部分 conn.setHostnameVerifier(new SslHandshakeExc_NsanMatchingIp().new TrustAnyHostnameVerifier()); conn.connect(); InputStream is = conn.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String line; while ((line = br.readLine()) != null) { System.out.println(line); } br.close(); is.close(); } // 定製Verifier public class TrustAnyHostnameVerifier implements HostnameVerifier { public boolean verify(String hostname, SSLSession session) { return true; } } }
四、補充說明
在建立 SSL 連線時,HttpsClient 步驟並進行基本的伺服器身份驗證,以防止 URL 欺騙,其中包括驗證伺服器的名稱是否在證書中
HttpsClient 主要使用 HostNameChecker 檢查主機名和證書中指定的名稱。如果失敗了,HostNameVerifier 就會出現,它被用來驗證主機名
在 HostNameVerifier 沒有被重寫時,預設是這個驗證是錯誤的,也就意味著 HostNameChecker 失敗後就會丟擲這個異常
HostNameChecker 在實現上,如果傳入的主機名是 IP 地址,將由 matchIP 方法在可用的條目中搜索IP地址對應的名稱,同時在沒有條目可以提供和IP地址匹配的名稱時丟擲 CertificateException 異常
所以,如果想通過使用 IP 作為主機名連線,證書中應該包含名稱和與其匹配的 IP 地址這個條目