• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
山高我为峰
博客园    首页    新随笔    联系   管理    订阅  订阅
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";
    }

}

 

posted on 2018-07-24 17:23  山高我为峰  阅读(3999)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3