线程 6,RECV TLSv1 ALERT:致命,handshake_failure

Posted

技术标签:

【中文标题】线程 6,RECV TLSv1 ALERT:致命,handshake_failure【英文标题】:Thread-6, RECV TLSv1 ALERT: fatal, handshake_failure 【发布时间】:2015-08-29 23:31:19 【问题描述】:

这段代码有什么问题,它应该信任所有主机,但它没有..

它适用于例如 google.com,但不适用于在我的机器上本地运行的 API 网关服务,为什么?

SSL 调试输出

触发 SecureRandom 播种完成播种 SecureRandom Ignoring 不支持的密码套件:TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 ... 忽略不支持的密码套件:TLS_RSA_WITH_AES_128_CBC_SHA256 允许不安全的重新协商:false 允许遗留的 hello 消息:true 是 初始握手:true 是否安全重新协商:false Thread-6, setSoTimeout(0) 调用 %% 没有缓存的客户端会话 *** ClientHello,TLSv1 RandomCookie:GMT:1434280256 字节 = 216 ... 40 会话 ID: 密码套件: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, .... SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA、SSL_RSA_WITH_RC4_128_MD5、 TLS_EMPTY_RENEGOTIATION_INFO_SCSV] 压缩方法: 0 扩展椭圆曲线,曲线名称:secp256r1 .. secp256k1 扩展 ec_point_formats,格式:[未压缩]

线程 6,写入:TLSv1 握手,长度 = 163 线程 6,读取:TLSv1 警报,长度 = 2 Thread-6,RECV TLSv1 ALERT:致命, handshake_failure 线程 6,调用 closeSocket() 线程 6,处理 异常:javax.net.ssl.SSLHandshakeException:**

收到致命警报:handshake_failure


**

import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.net.URLConnection;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;

public class ConnectHttps 
  public static void main(String[] args) throws Exception 
    /*
     *  fix for
     *    Exception in thread "main" javax.net.ssl.SSLHandshakeException:
     *       sun.security.validator.ValidatorException:
     *           PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:
     *               unable to find valid certification path to requested target
     */
    TrustManager[] trustAllCerts = [
        [ getAcceptedIssuers:  -> null ,
          checkClientTrusted:  X509Certificate[] certs, String authType -> ,
          checkServerTrusted:  X509Certificate[] certs, String authType ->  ] as X509TrustManager
    ]

    SSLContext sc = SSLContext.getInstance("SSL");
    sc.init(null, trustAllCerts, new java.security.SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

    // Create all-trusting host name verifier
    HostnameVerifier allHostsValid = new HostnameVerifier() 
        public boolean verify(String hostname, SSLSession session) 
          return true;
        
    ;
    // Install the all-trusting host verifier
    HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
    /*
     * end of the fix
     */

    //URL url = new URL("https://google.com"); //WORKS
    URL url = new URL("https://localhost:8090");   // DOES NOT WORK, WHY?
    URLConnection con = url.openConnection();
    Reader reader = new InputStreamReader(con.getInputStream());
    while (true) 
      int ch = reader.read();
      if (ch==-1) 
        break;
      
      System.out.print((char)ch);
    
  

运行the code found here表明客户端没有启用TLSv1.2:

支持的协议:5 SSLv2Hello SSLv3 TLSv1 TLSv1.1 TLSv1.2

启用的协议:2 SSLv3 TLSv1

【问题讨论】:

【参考方案1】:

.. 它应该信任所有主机,但它不..

.. RECV TLSv1 ALERT: 致命,handshake_failure Thread-6

来自服务器的握手失败警报与客户端上的服务器证书验证无关,因此无法通过禁用证书验证来停止。很多事情都可能导致这样的失败,比如没有通用密码、不受支持的协议版本、缺少 SNI 扩展(仅支持从 JDK7 开始)。由于错误是由服务器发出的,您可能会在服务器日志消息中找到有关该问题的更多详细信息。

编辑:从服务器日志中可以看到问题的原因:

错误处理连接:SSL 协议错误错误:1408A0C1:SSL 例程:SSL3_GET_CLIENT_HELLO:no shared cipher

这意味着客户端和服务器之间没有通用密码。

造成这种情况的典型原因是服务器上的证书设置错误。如果您未配置任何证书,则服务器可能需要使用 ADH 密码进行匿名身份验证,这通常不会在客户端启用。我建议你检查一下你是否可以用浏览器连接。

另一个常见的错误配置是禁用服务器上的所有 SSLv3 密码,认为这是禁用 SSL3.0 协议所必需的(事实并非如此)。这有效地禁用了所有密码,除了 TLS 1.2 引入的一些新密码。现代浏览器仍然可以连接,但旧客户端不能。在这种情况下可以看到这种错误配置(来自评论):

来自服务器日志,接口密码:FIPS:!SSLv3:!aNULL,,

!SSLv3 禁用 SSL3.0 及更高版本的所有可用密码。这实际上只留下了 TLS1.2 密码,因为没有 TLS1.0 和 TLS1.1 的新密码。由于客户端似乎只支持 TLS1.0,所以不会有共享密码:

...写:TLSv1 握手

在密码中使用!SSLv3通常是由于对协议版本和密码之间的区别缺乏了解造成的。要禁用 SSLv3,您应该只相应地设置协议,而不是密码。

【讨论】:

感谢有关服务器日志的建议,但它们并没有让我变得更聪明......错误 14/Jun/2015:13:56:03.746 [00cc] [SSL 警报写入 00000228、00002112 ]:握手失败[致命]。错误 14/Jun/2015:13:56:03.746 [00cc] [SSL_accept, 00002112]:错误 - SSLv3 读取客户端 hello C。错误 14/Jun/2015:13:56:03.746 [00cc] [SSL_accept, 00002112]:错误 - SSLv3 读取客户端 hello C. ERROR 14/Jun/2015:13:56:03.747 [00cc] error handling connection: SSL protocol error error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher, source location: .\ssl\ s3_srvr.c:1360 @user955732:服务器日志显示问题。请参阅编辑后的答案。 @user955732:然后您应该检查在服务器上配置了哪些密码(查看服务器配置)并确保这些密码中至少有一个在客户端可用。请参阅编辑了解更多信息。 从服务器日志,接口密码:FIPS:!SSLv3:!aNULL,,尝试在客户端设置 https.protocols 属性,System.setProperty("https.protocols", " TLSv1,SSLv3,SSLv2Hello"); ,,但还是没有运气... @user955732: !SSLv3 的密码正是错误的地方。请参阅编辑后的答案。

以上是关于线程 6,RECV TLSv1 ALERT:致命,handshake_failure的主要内容,如果未能解决你的问题,请参考以下文章

There was a problem confirming the ssl certificate: [SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert

mac下python环境pip报错[SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:590) 的解决方法

无法安装 Python 包 [SSL: TLSV1_ALERT_PROTOCOL_VERSION]

问题与解决Github 上传代码报错(error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version

OpenSSL: error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version

git提交报错SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version