首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Https全揭秘系列-故障经验总结

Https全揭秘系列 - 故障经验总结

今天总结下https握手失败的各种可能原因,下面列出的每种情况都是项目中实际遇到的。

1.基础篇

在第一章我将列举出一些比较容易排查的问题。

1.1 TLS版本不一致

我们曾经讲过Https握手协议有多个版本(SSL,TLSV1.0,TLSV1.1,TLSV1.2),那么这么多版本之前有什么区别呢?答案就是加密套件(Cipher Cuite)。

随着科技的发展,许多旧的加密算法被证明是不安全的,那么在新的tls协议中就将移除不安全的加密算法,增加新的安全的加密算法。那么当客户端和服务端使用不同的tls握手协议时就有可能导致客户端和服务端没有通用的加密套件,这时服务端就会主动断开连接。

这种情况排查非常容易,首先我们先模拟出这种场景,使用以前文章中的代码,将服务端tls版本设置为tlsv1.0(修改客户端版本同理),启动两端开始握手,在wireshark抓包中我们可以明显看到客户端在发送了client hello之后服务端没有返回正常的server hello包,而是直接返回失败。

我们查看服务端的日志发现jvm打印出了详细的错误原因,就是下面的信息。

注意到了no cipher suites in common这行信息了么。

关于tls版本还有一个需要特别注意的点,就是tls版本与jdk版本密切相关,jdk6某些版本只支持tlsv1.0,jdk7支持tlsv1.0,v1.1和v1.2,而jdk8只支持tlsv1.1和1.2。详细指定关系可参照下图。

1.2客户端不信任服务端发送的证书

这种情况其实就是客户端truststore中没有服务端的证书,有可能服务端提供的证书有误或者客户端导入有问题。

我们首先模拟出这种情况,使用正确的keystore和truststore,到jdk的bin目录下执行下面命令删除保存在客户端truststore中的服务端证书,然后客户端证书到客户端的truststore中(这一步是为了保证truststore不为空,truststore为空时在Https握手时会抛出异常:java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty),修改代码中的路径启动两端。

抓包如上图所示,服务端在完成server hello down发送完自己证书后客户端直接返回了报错信息关闭了连接,我们查看客户端的jvm输出信息可以看到下面字段

至于发现这种情况后如何解决可以参照上一篇文章,对比包中的证书信息与truststore中是否一致,不一致则修改服务端或者客户端相关配置即可。

1.3服务端不信任客户端证书

这种与上面情况刚好相反,不过原理完全一样不再赘述。

使用正确的keystore和truststore执行下面命令删除保存在服务端和客户端证书,修改代码路径启动两端。

抓包如下,深色的为服务端发送的包,可以看到客户端校验服务端证书通过后发送了自己的证书,不过服务端紧接着直接返回了报错。

查看服务端JVM信息

2.提高篇

本篇中我将分享一个比较难排查,难以想象的jdk bug(写文章前一直以为是bug,最近发现也不算bug,只是一个极其隐晦的逻辑,oracle没有明确指出)

我们以前讲过keystore和truststore有很多种格式,其中jks格式为jdk默认的格式,常用的还有pkcs等等,我们这次使用pkcs12格式重新生成同样的keystore和truststore,生成命令如下:

现在,我们加载刚才生成的keystore和truststore使用JDK1.8启动服务端和客户端,那么一切都正常,握手成功。

现在我们将JDK换成1.7或者1.6再次启动服务端和客户端,我们会发现握手失败了,并且在客户端校验就失败了,也就是说客户端不信任服务端的证书了。

问题出在哪里呢,答案是truststore上,JDK1.6和JDK1.7并不支持PKCS12格式的truststore,因为对于PKCS12格式的truststore,除了提供包含公钥的证书还需要包含私钥才能被加载为可信任证书。

事实上,你不可能要求对端将自己的私钥也发送给自己,因为私钥是绝对保密的。这也就意味着对于JDK1.6和JDK1.7,可以使用PKCS12格式的keystore,但是不能使用PKCS12格式的truststore。

但是在JDK1.8,这个逻辑被修复了,也就是说你可以像使用JKS格式一样使用PKCS12格式的keystore和truststore。

我在我的HttpsExample项目中提供了今天文章所用到的所有keystore和truststore文件,有兴趣的可以下载下来验证一下。

到此为止,Https系列文章暂时告一段落,接下来我将开个Java集合类的坑。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20171214G0C2XP00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券