通过Java代码使用HttpURLConnection去连接https系统时候总是报错handshake_failure。而使用浏览器访问一切正常。记录下诊断的过程。

HttpURLConnection的调用非常简单。

 
HttpURLConnection connection =(HttpURLConnection)m_url.openConnection();connection.setRequestMethod("GET");
connection.setAllowUserInteraction(false);
connection.setDefaultUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(false);
connection.setInstanceFollowRedirects(true);
connection.setUseCaches(false);
connection.connect(); <----- handshake error

错误也很抽象。

 
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failureat sun.security.ssl.Alerts.getSSLException(Unknown Source)at sun.security.ssl.Alerts.getSSLException(Unknown Source)at sun.security.ssl.SSLSocketImpl.recvAlert(Unknown Source)at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(Unknown Source)at com.agile.common.HttpReader.getInputStream(HttpReader.java:76)

初步怀疑本地的JRE证书信任文件中没有包含对方服务器的根证书。

 
keytool -list -v -keystore "C:\Java\jdk1.8.0_152\jre\lib\security\cacerts" >store.txt

检查发现,根证书和中间证书都存在,信任链没有问题。

 
## 中间证书
Alias name: comodorsaca [jdk]
Creation date: 25 Aug, 2016
Entry type: trustedCertEntryOwner: CN=COMODO RSA Certification Authority, O=COMODO CA Limited, L=Salford, ST=Greater Manchester, C=GB
Issuer: CN=COMODO RSA Certification Authority, O=COMODO CA Limited, L=Salford, ST=Greater Manchester, C=GB
Serial number: 4caaf9cadb636fe01ff74ed85b03869d
Valid from: Tue Jan 19 05:30:00 IST 2010 until: Tue Jan 19 05:29:59 IST 2038
Certificate fingerprints:MD5:  1B:31:B0:71:40:36:CC:14:36:91:AD:C4:3E:FD:EC:18SHA1: AF:E5:D2:44:A8:D1:19:42:30:FF:47:9F:E2:F8:97:BB:CD:7A:8C:B4SHA256: 52:F0:E1:C4:E5:8E:C6:29:29:1B:60:31:7F:07:46:71:B8:5D:7E:A8:0D:5B:07:27:34:63:53:4B:32:B4:02:34Signature algorithm name: SHA384withRSAVersion: 3## 根证书
Alias name: addtrustqualifiedca [jdk]
Creation date: 25 Aug, 2016
Entry type: trustedCertEntryOwner: CN=AddTrust Qualified CA Root, OU=AddTrust TTP Network, O=AddTrust AB, C=SE
Issuer: CN=AddTrust Qualified CA Root, OU=AddTrust TTP Network, O=AddTrust AB, C=SE
Serial number: 1
Valid from: Tue May 30 16:14:50 IST 2000 until: Sat May 30 16:14:50 IST 2020
Certificate fingerprints:MD5:  27:EC:39:47:CD:DA:5A:AF:E2:9A:01:65:21:A9:4C:BBSHA1: 4D:23:78:EC:91:95:39:B5:00:7F:75:8F:03:3B:21:1E:C5:4D:8B:CFSHA256: 80:95:21:08:05:DB:4B:BC:35:5E:44:28:D8:FD:6E:C2:CD:E3:AB:5F:B9:7A:99:42:98:8E:B8:F4:DC:D0:60:16Signature algorithm name: SHA1withRSAVersion: 3

那就去抓SSL包吧。

请求包:

 
Secure Sockets LayerTLSv1.2 Record Layer: Handshake Protocol: Client HelloContent Type: Handshake (22)Version: TLS 1.2 (0x0303)Length: 229Handshake Protocol: Client HelloHandshake Type: Client Hello (1)Length: 225Version: TLS 1.2 (0x0303)Random: 5af01897734438e606e3342398727fe8a539522a2ef0dfa6...GMT Unix Time: May  7, 2018 17:12:55.000000000 中国标准时间Random Bytes: 734438e606e3342398727fe8a539522a2ef0dfa6b698a1eb...Session ID Length: 0Cipher Suites Length: 58Cipher Suites (29 suites)Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (0xc023)Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027)Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA256 (0x003c)Cipher Suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 (0xc025)Cipher Suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 (0xc029)Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (0x0067)Cipher Suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 (0x0040)Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009)Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)Cipher Suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA (0xc004)Cipher Suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA (0xc00e)Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x0033)Cipher Suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA (0x0032)Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c)Cipher Suite: TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02d)Cipher Suite: TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 (0xc031)Cipher Suite: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (0x009e)Cipher Suite: TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 (0x00a2)Cipher Suite: TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA (0xc008)Cipher Suite: TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (0xc012)Cipher Suite: TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a)Cipher Suite: TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA (0xc003)Cipher Suite: TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA (0xc00d)Cipher Suite: TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA (0x0016)Cipher Suite: TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA (0x0013)Cipher Suite: TLS_EMPTY_RENEGOTIATION_INFO_SCSV (0x00ff)

响应包:

 
Secure Sockets LayerTLSv1.2 Record Layer: Alert (Level: Fatal, Description: Handshake Failure)Content Type: Alert (21)Version: TLS 1.2 (0x0303)Length: 2Alert MessageLevel: Fatal (2)Description: Handshake Failure (40)

客户端发送了Hello,服务器翻了个白眼直接拒绝了。这个响应包,没有任何线索。但是能明确一点就是客户端和服务器都通过TLS 1.2协议协商。不用再怀疑协议版本问题了。

联想到浏览器访问对方https系统是成功的,再次抓取浏览器请求和响应包。发现了一点有用的线索。

浏览器的请求包同样采用TLS 1.2协议,但是加密套件 (Cipher Suites)和前面的差异很大,提供了17个可选加密套件。前面的包提供了29个可选列表。

 
Secure Sockets LayerTLSv1.2 Record Layer: Handshake Protocol: Client HelloContent Type: Handshake (22)Version: TLS 1.0 (0x0301)Length: 512Handshake Protocol: Client HelloHandshake Type: Client Hello (1)Length: 508Version: TLS 1.2 (0x0303)Random: 7179caea804a5281b411adca67c11883f616e13e13756d0d...GMT Unix Time: May  1, 2030 03:20:10.000000000 中国标准时间Random Bytes: 804a5281b411adca67c11883f616e13e13756d0d5764d936...Session ID Length: 32Session ID: 324885cac7ecf4dd09e38acdd3e45ceb2e0c5e248b31d267...Cipher Suites Length: 34Cipher Suites (17 suites)Cipher Suite: Reserved (GREASE) (0xcaca)Cipher Suite: TLS_AES_128_GCM_SHA256 (0x1301)Cipher Suite: TLS_AES_256_GCM_SHA384 (0x1302)Cipher Suite: TLS_CHACHA20_POLY1305_SHA256 (0x1303)Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c)Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)Cipher Suite: TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9)Cipher Suite: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8)Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c)Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d)Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)Cipher Suite: TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a)

接着看浏览器接收到的tcp包Server Hello。服务器通过TLS 1.2协议协商,告诉浏览器它要使用 TLS_RSA_WITH_AES_256_GCM_SHA384 加密套件作为后续数据的加密算法。

 
Secure Sockets LayerTLSv1.2 Record Layer: Handshake Protocol: Server HelloContent Type: Handshake (22)Version: TLS 1.2 (0x0303)Length: 81Handshake Protocol: Server HelloHandshake Type: Server Hello (2)Length: 77Version: TLS 1.2 (0x0303)Random: f1649150aeb3366381e54392bfdb8f49ae8ead9f47dbcb1f...GMT Unix Time: May  3, 2098 04:10:56.000000000 中国标准时间Random Bytes: aeb3366381e54392bfdb8f49ae8ead9f47dbcb1fc13f95a4...Session ID Length: 32Session ID: 264c4906bbd0fd2b8f94f66ea2992433b82690fb7fb844d7...Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d)Compression Method: null (0)Extensions Length: 5Extension: renegotiation_info (len=1)Type: renegotiation_info (65281)Length: 1Renegotiation Info extensionRenegotiation info extension length: 0

马上注意到在前面的请求包中,29个加密套件里都没有TLS_RSA_WITH_AES_256_GCM_SHA384。似乎问题就在这里,就是通过java代码访问https服务器时,候选的加密套件中没有服务器希望的TLS_RSA_WITH_AES_256_GCM_SHA384。

真的是这样吗?为了弄清服务器和本地JRE是否存在加密套件不匹配,还得使用有足够说服力的诊断方法来验证。

首先搬上OPENSSL来调试。

 
openssl s_client -connect server.mycompany.com:443

诊断发现,服务器确实需要AES256-GCM-SHA384,这是一个很长长度的强加密,一般128位长度加密很牛逼了。

 
New, TLSv1.2, Cipher is AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:Protocol  : TLSv1.2Cipher    : AES256-GCM-SHA384Session-ID: 5BFE44E0BE1248156266BE6947FA113C1035DDDC3A3BD1888940EF8257CAA18C

对Java代码也来一次调试,确认它所支持的所有加密套件。

 
-Dssl.debug=true -Djavax.net.debug=all

返回结果确实如此,根本就不存在TLS_RSA_WITH_AES_256_GCM_SHA384,也不存在基于AES256-GCM-SHA384的加密方法。

 
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]

问题找到了。解决方法看来现在只能回到JRE本身的加密授权问题上来了。

Java支持所有的加密套件,但是对于发行的JDK版本,它默认做了很多加密长度限制的裁剪,就是只出口强度低的加密,这是美国政府对于安全软件的强制性规定。但Oracle允许下载强加密的未限制版本,其实就是几个授权属性文件,因为源代码都在发行的JDK中。

当前问题发生在JDK1.8中,所以可以去官网下载一个压缩包叫做 “Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 8”。

对于JDK1.8版本但是低于1.8.0_151版本的JDK,将下载的包里的两个文件直接覆盖到本地 Java\jre\lib\security\

 
local_policy.jar
US_export_policy.jar

1.8.0_151和以后的版本,无需下载任何文件,只要修改Java\jre\lib\security\java.security文件,修改这一行注释并启用就可以了。

 
crypto.policy=unlimited

Java加密套件强度限制引起的SSL handshake_failure相关推荐

  1. java实现HTTPS单向认证TLS指定加密套件(文章很详细,好文章!)

    1.HTTPS介绍 由于HTTP是明文传输,会造成安全隐患,所以在一些特定场景中,必须使用HTTPS协议,简单来说HTTPS=HTTP+SSL/TLS.服务端和客户端的信息传输都是通过TLS进行加密. ...

  2. 客户端和服务器不支持一般 ssl 协议版本或加密套件。_恶意软件加密通信概要分析...

    作者:Jo@北京观成科技 恶意加密流量是当前流量安全检测的痛点和难点.在未解密的情况下如何检测恶意加密流量,机器学习可提供颇为有效的解决方案.传统机器学习依赖于训练数据集和特征工程,而搜集的各类恶意加 ...

  3. Windows 11和Windows 2022 TLS/SSL(Schannel SSP)的加密套件

    一.TLS/SSL(Schannel SSP)加密套件简介 TLS/SSL(Schannel SSP)加密套件是一组密码编译演算法.TLS/SSL 通讯协定的安全通道SSP 实作会使用加密套件中的演算 ...

  4. 谷歌浏览器提示客户端和服务器不支持一般 SSL 协议版本或加密套件(亲测有效)

    目录 一.定位问题 二.升级TLS1.2 1.原理 之前架构 调整架构 2.配置nginx 3.配置tomcat 三.访问nginx即可 最近访问一部分网站时,出现如下图所示 " 此网站无法 ...

  5. 带你轻松认识SSL协议中的加密套件

    什么是加密套件 加密套件(CipherList)是指在ssl通信中,服务器和客户端所使用的加密算法的组合.在ssl握手初期,客户端将自身支持的加密套件列表发送给服务器:在握手阶段,服务器根据自己的配置 ...

  6. 客户端和服务器不支持一般 ssl 协议版本或加密套件。_SSL:握手过程详解

    1. client--->server:Client hello Version: TLS 1.2:客户端使用的 TLS 版本号. Session ID:会话 ID,首次连接时该字段为空,即 S ...

  7. 此网站无法提供安全连接(客户端和服务器不支持一般 SSL 协议版本或加密套件。)

    最近访问一部分网站时,出现如下图所示 " 此网站无法提供案例连接,客户端和服务器不支持一般 SSL 协议版本或加密套件 " 的问 题. 注意这里显示了非常关键的一句话,xxx使用了 ...

  8. Java加密与解密的艺术~安全协议~单向认证服务

    1.准备工作 A.域名绑定 在hosts文件末尾追加 127.0.0.1  www.zlex.org B.证书导入 浏览器导入自签名证书文件zlex.cer C.服务器配置 配置SSL/TLS 单向认 ...

  9. java加密与解密(二)

    七. 高等数据加密--非对称加密算法         我们可能没有在瑞士苏黎世银行存入巨额资产的机会,但相信大多数人都在电影中见到这样一组镜头:户主带着自己的钥匙来到银行,要求取出自己寄放的物品.银行 ...

  10. Java加密与解密笔记(三) 非对称加密

    非对称的特点是加密和解密时使用的是不同的钥匙.密钥分为公钥和私钥,用公钥加密的数据只能用私钥进行解密,反之亦然. 另外,密钥还可以用于数字签名.数字签名跟上文说的消息摘要是一个道理,通过一定方法对数据 ...

最新文章

  1. android换肤动画,Android-换肤ThemeSkinning使用
  2. 又是读了多个文件没关闭,搞死了一晚
  3. Linux-Iptables-Memcached实现内网转发连接
  4. python setup用法_python的构建工具setup.py的方法使用示例
  5. 如何找出标有App Store 精华,Essentials的所有软件?
  6. 课程升级 | 极速构建知识体系,即学即用 Serverless
  7. Rocket - tilelink - FIFOFixer
  8. Windows 2003安装IIS无法复制CONVLOG.EXECONVLOG.EX_问题
  9. oracle安装gcc报错,记录oracle 9i for linux安装过程中几个错误
  10. CentOS 7 安装Mono 和 MonoDevelop
  11. pycharm 怎么快速生成文件夹结构_Pycharm配置Qt工具(ubuntu18.04)
  12. 科工网大数据有力促进机器人制造业发展
  13. 通达oa2017 数据库表结构
  14. UE4 实时渲染原理优化策略笔记
  15. oracle数据库报01033,oracle数据库报ORA-01033错误
  16. 递归应用之谢尔宾斯基三角形Python
  17. 定制材料 Pd基聚多巴胺包裹碳纳米管/Fe或Cr单原子链填充Cu纳米管/Fe@CuNT和Cr@CuNT复合结构/氧化钼包裹碳纳米管纳米复合纤维
  18. Win7和Win10如何使文件的视图默认按详细信息显示
  19. html增加语音朗读功能,给wordpress主题添加上语音播放文章内容文本朗读功能
  20. 基于Linux下 Oracle 备份策略(RMAN)---转自沙弥的世界

热门文章

  1. 超硬核!第16届CLK大会完整议程全公布!
  2. 协议栈数据包快速转发的实现(2)
  3. 解决使用CSDN下载东西时,点击直接下载没有反应的问题
  4. RFC请求注解(Request for Comments)介绍|internet最重要的文献资源
  5. Java实现从第三方系统单点登录到致远OA
  6. DNS服务器常见的攻击方式
  7. 身份证有效验证方法,
  8. win10专业版和企业版的区别
  9. 远程时无法打开Internet站点
  10. 正则匹配十六进制的色值,以#号开头