【问题标题】:Getting an exception javax.net.ssl.SSLHandshakeException: Received fatal alert: protocol_version获取异常 javax.net.ssl.SSLHandshakeException:收到致命警报:protocol_version
【发布时间】:2021-11-02 11:49:15
【问题描述】:

我创建了一个网络爬虫,它将返回一个 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。

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

【问题讨论】:

  • httpclient-4.5.13 是 2020 年 10 月 6 日,所以我假设警报是“新客户端,旧服务器”,如果您的协议不匹配,在证书验证的问题甚至出现了。如果要启用旧协议:*.com/questions/31608243/…
  • 感谢您的回复。我的思绪在同一个方向徘徊。 .我将尝试您提供的链接中的代码。
  • 感谢您的帮助,遗憾的是它没有工作 SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory( SSLContext.getDefault(), // new String[] { "SSLv2Hello","SSLv3","TLSv1","TLSv1 .1","TLSv1.2"}, new String[] { "SSLv3","TLSv1.2"}, null, (s, sslSession) -> true);仍然返回 javax.net.ssl.SSLHandshakeException: Received fatal alert: protocol_version

标签: java spring-boot ssl


【解决方案1】:

好的,这适用于 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());

【讨论】: