记一次HTTPS请求握手异常的排查与反思

问题描述
今天我们系统在做业务时,需要访问外部银行环境,而此时报错,异常如下:
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
在这里插入图片描述
问题排查
通过日志发现,系统报了SSLHandshakeException,而这个错误是一个SSL告警异常。也就是客户端在向服务器发送HTTPS请求时,需要先和服务器建立SSL连接(本质上也是一种三次握手),建立完连接后,才能进行加密数据传输。
通过日志进一步发现,客户端与服务器采用的协议不同,客户端采用了TLSv1协议,而服务器端采用了SSLv3协议,两者的协议不同,导致了握手异常。
客户端协议的选择
发现原因后,需要考虑如何让客户端选择和服务器的协议。首先分析客户端的协议选择。
通过网上资料,我发现不同的JDK所采用的默认SSL协议不同,如下图所示:
在这里插入图片描述
通过上图,我们发现JDK1.7采用的默认版本是TLSv1协议,这也就解释了为什么客户端会选择该协议了。
解决方案
发现问题后,我检查了服务器的JDK版本为JDK1.7,确实符合这种情况。但是,我们公司的另一台服务器的JDK版本也为JDK1.7,可是这台机器却不会报错。但是两台机器的版本有所差异,一台是jdk1.7.0.79版本,另一台却是jdk1.7.0.65版本。难道不同的小版本存在差异性?
验证
将该机器的jdk版本也改为jdk1.7.0.65版本,结果访问外部银行环境后,显示验证成功!
在这里插入图片描述
此时客户端也采用SSLv3协议了!
最终结论如下:通过JDK版本问题可以解决该问题
jdk1.7.0.79版本禁用了SSLv3协议,而外部银行使用的就是SSLv3协议,所以报错。
修改JDK版本为jdk1.7.0.65版本后,完美解决问题!
反思
1.如何发现这种SSL问题?
答:通过JVM参数-Djavax.net.debug=ssl启动java ssl调试日志记录
2.何为HTTPS请求?
答:安全套接字层超文本传输协议HTTPS,为了数据传输的安全,HTTPS在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。当客户端需要发送一个HTTPS请求时,请求的建立过程如下:

  1. 客户端发起一个https请求;
    a) 客户端支持的加密方式;
    b) 客户端生成的随机数(第一个随机数);
  2. 服务端收到请求后,拿到随机数,返回;
    a) 证书(颁发机构(CA)、证书内容本身的数字签名(使用第三方机构的私钥加密)、证书持有者的公钥、证书签名用到的hash算法);
    b) 生成一个随机数,返回给客户端(第二个随机数);
  3. 客户端拿到证书以后做验证;
    a) 根据颁发机构找到本地的跟证书;
    b) 根据CA得到根证书的公钥,通过公钥对数字签名解密,得到证书的内容摘要 A;
    c) 用证书提供的算法对证书内容进行摘要,得到摘要 B;
    d) 通过A和B的对比,也就是验证数字签名;
  4. 验证通过以后,生成一个随机数(第三个随机数),通过证书内的公钥对这个随机数加密,发送给服务器端;
  5. (随机数1+2+3)通过对称加密得到一个密钥(主密钥)。后续通过 PRF 函数生成会话密钥;
  6. 通过会话密钥对内容进行对称加密传输;
    在这里插入图片描述3.其他
    第一,为什么HTTPS采用非对称加密方式传输对称密钥,而采用对称密钥传输会话数据?我通过对两种加密算法的比较发现,一般对称加密比非对称加密快很多(DES就比RSA快100倍)。而且,除此之外,非对称加密算法一次能加密的明文是有限的,使用 RSA 2048 公钥加密数据,每次加密的数据不能超过 245 个字节,互联网应用的数据都很大,用非对称加密算法那就得拆开来,那会更慢。所以一般通过非对称加密方式传输对称密钥,一旦双方确认对称密钥,后续则通过对称密钥传输会话数据。
    第二,我发现HTTPS的建立过程其实与建立TCP连接的过程类似,这个其实也很容易理解。因为HTTP连接其实就是基于TCP连接,正所谓底层基础决定上层建筑,所以有什么的爹就有什么样的娃,HTTPS连接过程与TCP三次握手的过程类似也就不足为奇了。
发布了19 篇原创文章 · 获赞 20 · 访问量 5854

猜你喜欢

转载自blog.csdn.net/qq_15898739/article/details/90298972