SSL - SSLHandshakeException: No subject alternative names matching IP address found

一、异常日志

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 地址这个条目


 

 

 

 

 

 

 

 

 

你可能感兴趣的:(J2SE)