首页 > 解决方案 > 获取异常 javax.net.ssl.SSLHandshakeException:收到致命警报:protocol_version

问题描述

我创建了一个网络爬虫,它将返回 URL 页面。对于某些 URL,我得到: javax.net.ssl.SSLHandshakeException: Received fatal alert: protocol_version

这样做的目的只是解析返回的网页。所以我正在寻找绕过的方法。SSL 验证

 (s, sslSession) -> true

所以我创建了一个 SSLConnectionSocketFactory

private SSLConnectionSocketFactory sslFactory() {
             SSLContext sslcontext = null;
             try {
                    sslcontext = SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build();

             } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
             }
              SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslcontext, (s, sslSession) -> true);

             return sslConnectionSocketFactory;
       }

然后将其添加到 HTMLClient

var clientBuilder  = HttpClientBuilder.create()
        .setDefaultRequestConfig(RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build())
                .setRedirectStrategy(new LaxRedirectStrategy())
                .setDefaultCookieStore(cookieStore)
                .setSSLSocketFactory(sslFactory());

根据我的研究,这应该绕过 SSL 验证,但它仍然抛出异常。我正在使用 httpclient-4.5.13。

我了解安全隐患,但这是在解析网页,它不会发送任何数据。谢谢你的帮助。

标签: javaspring-bootssl

解决方案


好的,这适用于 httpclient-4.5.13 java 11,它不适用于 Java 16。所以设置受信任的证书。

private SSLContext SSLConnection() throws NoSuchAlgorithmException, KeyManagementException {
        TrustManager[] trustAllCerts = new TrustManager[] {
                   new X509TrustManager() {
                      public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return null;
                      }
                      public void checkClientTrusted(X509Certificate[] certs, String authType) {  }
                      public void checkServerTrusted(X509Certificate[] certs, String authType) {  }
                   }
                };
                SSLContext sc = SSLContext.getInstance("SSL");
                sc.init(null, trustAllCerts, new java.security.SecureRandom());
                return sc;
    }

并将其添加到 clientBuilder

 var clientBuilder  = HttpClientBuilder.create()
                 .setDefaultRequestConfig(RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build())
                    .setRedirectStrategy(new LaxRedirectStrategy())
                    .setDefaultCookieStore(cookieStore)
                    .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
                    .setSSLContext(SSLConnection());

推荐阅读