javax.net.ssl.SSLException: Certificate doesn't match any of the subject alternative names

问题:在使用 org.apache.http.*下的 CloseableHttpClient 发送https请求时报了以上错误

解决方案一:使用java.net.HttpURLConnection 

import java.net.HttpURLConnection;

public static HttpURLConnection connectToWeb(String uri) {
    HttpURLConnection connection = null;
    try {
        URL url = new URL(uri);
        connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        connection.connect();
    } catch (MalformedURLException ex) {
        ex.printStackTrace();
    } catch (IOException ex) {
        ex.printStackTrace();
    }
    return connection;
}

解决方案二:在创建SSLConnectionSocketFactory时,添加NoopHostnameVerifier.INSTANCE参数

 public static CloseableHttpClient createSSLClientDefault() {
        CloseableHttpClient client = null;
        try {
            SSLContext sslContext = null;
            sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                @Override
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    return true;
                }
            }).build();
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);//这里的红色部分
            client = HttpClients.custom().setSSLSocketFactory(sslsf).build();
        } catch (NoSuchAlgorithmException | KeyStoreException | KeyManagementException e) {
            e.printStackTrace();
        }
        return client;
    }

原理扩展:

在org.apache.http.conn.ssl.SSLConnectionSocketFactory.verifyHostname方法中有如下代码:

而NoopHostnameVerifier源代码如下;verify方法直接返回true

/**
* The NO_OP HostnameVerifier essentially turns hostname verification
* off. This implementation is a no-op, and never throws the SSLException.
* 关闭主机名验证,直接返回true
* @since 4.4
*/
@Contract(threading = ThreadingBehavior.IMMUTABLE)
public class NoopHostnameVerifier implements HostnameVerifier {

    public static final NoopHostnameVerifier INSTANCE = new NoopHostnameVerifier();

    @Override
    public boolean verify(final String s, final SSLSession sslSession) {
        return true;
    }

    @Override
    public final String toString() {
        return "NO_OP";
    }

}
原文地址:https://www.cnblogs.com/liaojie970/p/9361320.html