👽System.out.println(“👋🏼嗨,大家好,我是代码不会敲的小符,双非大四,Java实习中…”);
📚System.out.println(“🎈如果文章中有错误的地方,恳请大家指正!共同进步,共同成长✊”);
🌟System.out.println(“💡如果文章对您有所帮助,希望您可以三连支持一下博主噢🔥”);
🌈System.out.println("🚀正在完成计划中:接下来的三个月里,对梦想的追逐 ");
文章目录
- 背景
- 关于HTTP和HTTPS
- SSL/TSL
- SSL/TSL 协议通信原理
- TCP三次握手建立连接
- TCP四次挥手
- 最后
背景
产品提了一个bug,初步排查可能是因为对接oAuth2单点登录时,客户端使用的https协议和服务端的使用的https协议版本不相同。客户端使用的协议版本是SSL3,服务端使用使用的协议版本是TSL1.2。所以上午补了一下关于https的SSL/TLS的基础知识
关于HTTP和HTTPS
访问网站时,以HTTPS开头的表示你和服务器之间传输的数据经过了加密,这里所使用的加密协议就是SSL(Secure Sockets Layer,后来又推出了它的后续版本,改名叫TLS)。把HTTP协议经过一层SSL协议进行加密包装,就变成了HTTPS。当然,SSL/TLS还用在很多协议中,例如VPN、加密的电子邮件协议等。
SSL(Secure Socket Layer)安全套接层
TLS(Transport Layer Security)传输层安全协议(SSL的后续版本)
TLS的主要目标是使SSL更安全,并使协议的规范更精确和完善。TLS 在SSL v3.0 的基础上,提供了以下增强内容:
- 更安全的MAC算法
- 更严密的警报
- “灰色区域”规范的更明确的定义
SSL/TSL
jdk1.8默认为TSL1.2
OPENSSL
在SSL协议中,我们使用了很多密码学手段来保护数据,其中包括对称密码、公钥密码、数字签名、证书、完整性校验、伪随机数生成等。OpenSSL是一套开源的密码学工具包(open source cryptography toolkit),是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及 SSL 协议,并提供丰富的应用程序供测试或其他的目的使用。
- Libencrpt:加解密库
- Libssl:实现ssl安全通信机制的库
- Openssl:多用途命令行工具
SSL/TSL 协议通信原理
会话握手的四个阶段,"握手阶段"的所有通信都是明文的 。
- 客户端发出请求(ClientHello):客户端(通常是浏览器、sso的客户端)先向服务器发出加密通信的请求,这被叫做ClientHello请求。在这一步,客户端主要向服务器提供以下信息
-
产生一个随机数,这个随机数一方面需要在客户端保存,另一方面需要传送给服务端
- 支持的协议版本,比如TLS 1.2版。
- 一个客户端生成的随机数,稍后用于生成"对话密钥"。
- 支持的加密方法,比如RSA公钥加密。
- 支持的压缩方法。
注意: 客户端发送的信息之中不包括服务器的域名。也就是说,理论上服务器只能包含一个网站,否则会分不清应该向客户端提供哪一个网站的数字证书。这就是为什么通常一台服务器只能有一张数字证书的原因。
- 服务器回应(SeverHello):服务器收到客户端请求后,向客户端发出回应,这叫做SeverHello。服务器的回应包含以下内容。
-
服务端也需要产生一个随机数发送给客户端。客户端和服务端都需要使用这两个随机数来产生 Master Secret
- 确认使用的加密通信协议版本,比如TLS 1.0版本。如果浏览器与服务器支持的版本不一致,服务器关闭加密通信。
- 一个服务器生成的随机数,稍后用于生成"对话密钥"。
- 确认使用的加密方法,比如RSA公钥加密。
- 服务器证书。(如X509)
- 索要客户端证书(非必须),银行金融系统会需要,其它很少有网点会索取
- 客户端回应:客户端收到服务器回应以后,首先验证服务器证书。如果证书不是可信机构颁布、或者证书中的域名与实际域名不一致、或者证书已经过期,就会向访问者显示一个警告,由其选择是否还要继续通信。如果证书没有问题,客户端就会从证书中取出服务器的公钥。然后,向服务器发送下面三项信息。
- 一个随机数。该随机数用服务器公钥加密,防止被窃听。
- 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。
- 客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供服务器校验。
上面第一项的随机数,是整个握手阶段出现的第三个随机数,又称"pre-master key"。有了它以后,客户端和服务器就同时有了三个随机数【三个随机数通过一个密钥导出器最终导出一个对称密钥。安全性】,接着双方就用事先商定的加密方法,各自生成本次会话所用的同一把"会话密钥"。
- 服务器的最后回应:服务器收到客户端的第三个随机数 pre-master key 之后,计算生成本次会话所用的"会话密钥"。然后,向客户端最后发送下面信息。
- 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。
- 服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供客户端校验。
至此,整个握手阶段全部结束。接下来,客户端与服务器进入加密通信,就完全是使用普通的HTTP协议,只不过用"会话密钥"加密内容。
TCP三次握手建立连接
一开始,客户端和服务端都处于 CLOSE 状态。先是服务端主动监听某个端口,处于 LISTEN 状态
- 客户端会随机初始化序号(client_isn),将此序号置于 TCP 首部的「序号」字段中,同时把 SYN 标志位置为 1,表示 SYN 报文。接着把第一个 SYN 报文发送给服务端,表示向服务端发起连接,该报文不包含应用层数据,之后客户端处于 SYN-SENT 状态。
- 服务端收到客户端的 SYN 报文后,首先服务端也随机初始化自己的序号(server_isn),将此序号填入 TCP 首部的「序号」字段中,其次把 TCP 首部的「确认应答号」字段填入 client_isn + 1, 接着把 SYN 和 ACK 标志位置为 1。最后把该报文发给客户端,该报文也不包含应用层数据,之后服务端处于 SYN-RCVD 状态。
- 客户端收到服务端报文后,还要向服务端回应最后一个应答报文,首先该应答报文 TCP 首部 ACK 标志位置为 1 ,其次「确认应答号」字段填入 server_isn + 1 ,最后把报文发送给服务端,这次报文可以携带客户到服务端的数据,之后客户端处于 ESTABLISHED 状态。
服务端收到客户端的应答报文后,也进入 ESTABLISHED 状态。第三次握手是可以携带数据的,前两次握手是不可以携带数据的
TCP四次挥手
- 关闭连接时,客户端向服务端发送 FIN 时,仅仅表示客户端不再发送数据了但是还能接收数据。
- 服务端收到客户端的 FIN 报文时,先回一个 ACK 应答报文,而服务端可能还有数据需要处理和发送,等服务端不再发送数据时,才发送 FIN 报文给客户端来表示同意现在关闭连接。
- 客户端打算关闭连接,此时会发送一个 TCP 首部 FIN 标志位被置为 1 的报文,也即 FIN 报文,之后客户端进入 FIN_WAIT_1 状态。
- 服务端收到该报文后,就向客户端发送 ACK 应答报文,接着服务端进入 CLOSE_WAIT 状态。
- 客户端收到服务端的 ACK 应答报文后,之后进入 FIN_WAIT_2 状态。
- 等待服务端处理完数据后,也向客户端发送 FIN 报文,之后服务端进入 LAST_ACK 状态。
- 客户端收到服务端的 FIN 报文后,回一个 ACK 应答报文,之后进入 TIME_WAIT 状态
- 服务端收到了 ACK 应答报文后,就进入了 CLOSE 状态,至此服务端已经完成连接的关闭。
- 客户端在经过 2MSL 一段时间后,自动进入 CLOSE 状态,至此客户端也完成连接的关闭。
每一个方向都需要一个 FIN 和一个 ACK,因此通常被称为四次挥手。
注意:主动关闭连接的,才有 TIME_WAIT 状态
参考文章:
SSL/TLS原理详解
一篇文章读懂HTTPS TLS 1.2握手流程(中)
一文看懂SSL/TLS/OPENSSL/HTTPS
最后
慢慢的来,别着急!学会有质量的走过每一步
我是代码不会敲的小符,希望认识更多有经验的大佬,也在努力摸索出自己的道路
欢迎添加小符微信:A13781678921,一起加油