SSL协议学习
简介
SSL全称Secure Sockets Layer,即安全套接层。简而言之,它是一项标准技术,可确保互联网连接安全,保护两个系统之间发送的任何敏感数据,防止网络犯罪分子读取和修改任何传输信息,包括个人资料。两个系统可能是指服务器和客户端或两个服务器之间。
SSL与TSL
SSL最初由Netscape公司在1994年推出,此后,成为最为著名的Web安全机制,所有主要web浏览器都支持SSL。1996年发布的3.0版本是使用最广的版本(官方文档),但是2014年10月,Google发布在SSL 3.0中发现设计缺陷,建议禁用此一协议。Google在自己公司相关产品中陆续禁止回溯兼容,强制使用TLS协议。Mozilla也在11月25日发布的Firefox 34中彻底禁用了SSL 3.0。
TLS全称Transport Layer Security,即传输层安全性协议。是更为安全的升级版 SSL。TSL1.0(官方文档)是IETF将SSL标准化的结果,从技术上讲,TLS 1.0与SSL 3.0的差异非常微小。TLS随后又发布了1.1、1.2与1.3版本。其中1.3版本2018年才发布,支持的浏览器较少。所有TLS版本在2011年3月发布的RFC 6176中删除了对SSL的兼容,这样TLS会话将永远无法协商使用的SSL 2.0以避免安全问题。本文主要讲述SSL3.0内容
工作原理
SSL可以看做TCP/IP协议中的一层,位于应用层和传输层之间,属于一种附加层,没有改层也可以正常通信,但是缺少安全性。
SSL有3个子协议:握手协议、记录协议和警报协议
握手协议
这是客户端与服务端进行SSL通信时的第一个子协议,该协议会在客户端与服务端传输一系列信息,信息有如下三个字段:
- Type:类型字段,一共有10种类型,占1字节
- Length:表示消息长度,占3字节
- Content:消息参数,长度不固定
对于握手协议,一般分4个阶段
建立安全能力
握手的第一阶段包含两个消息:“client hello”和“server hello”。
首先客户端向服务器发送“client hello”消息,包含以下字段:
- Version:客户端支持的最高SSL协议版本
- Random:随机数,包含两个字段:32位日期时间和28位随机数
- Session ID:会话号,若为非0值,表示连接已建立,但是客户端要更新参数;为0表示要建立新连接
- Cipher suite:客户端支持的加密算法清单
- Compression method:客户端支持的压缩算法
可见“client hello”是将客户端的一些情况发送给服务端,以便连接的建立
服务端收到客户端消息后,返回“server hello”消息,字段和“client hello”相同,但用途不同:
- Version:表示客户端和服务端共同支持的最高SSL版本的最低版本,如一方支持3.0一方支持3.1,则选择3.0版本
- Random:同样包含32位日期时间和28位随机数
- Session ID:若客户端发送的位非0值,则使用客户端发送的值,否则服务端生成一个新的ID
- Cipher suite:服务器选择的加密算法
- Compression method:服务器选择的压缩算法
到此客户端与服务端在一些基本问题上达成共识,在这些共识的基础上进行后续步骤
服务器认证与秘钥交换
握手的第二阶段,该阶段只有服务器发送消息,客户端只接受消息。一般有以下几步:
- 服务端将自己的数字证书和到根CA的证书链发送给客户端,供客户端进行认证
- 在第一步没有发送证书时,这一步才会发送服务器的公钥到客户端(数字证书中包含公钥,所以有数字证书就不用这一步)
- 服务器请求客户端证书,这一步是可选的,不要求全部链接都进行客户端认证
- 该阶段结束,发送“ServerHelloDone”信息,不包含任何参数,等待客户端响应。
客户端认证与秘钥交换
握手的第三阶段,该阶段只有客户端发送消息,服务器只接受消息。一般有以下几步:
- 这一步是可选的,只有在服务端请求客户端证书时,客户端才发送自己的证书。对于服务器要求但客户端没有证书的情况,客户端发送“No certificate”消息,后续由服务端决定通信是否继续
- 秘钥交换,客户端生成48字节的预备秘密,用服务器公钥加密发送给服务器
- 证书验证,也只在服务器请求客户端证书时才执行。这一步客户端要证明自己是证书的所有者,一般将前面握手第一阶段中发送的随机数进行摘要并用自己私钥加密发送给服务端
完成阶段
这一阶段由客户端启动。一共有四个消息,首先客户端发送改变加密规范消息和完成消息,服务端也随后也发送这两个消息。
这阶段需要一个主秘密,它是由前一步中的预备秘密和第一阶段中客户端与服务端的随机数进行拼接后进行摘要后生产的。主秘密产生后再和第一阶段中客户端与服务端的随机数进行拼接然后再次进行摘要得到会话的对称秘钥。
根据之前的握手信息,如果客户端和服务端都能对Finish信息进行正常加解密且消息正确的被验证,则说明握手通道已经建立成功,接下来,双方可以使用上面产生的Session Secret对数据进行加密传输了。
记录协议
完成握手后,进入SSL记录协议,一般提供两个服务:保密性和完整性
SSL记录协议以要传输的信息位输入,首先进行分块,对每块可选的进行压缩,然后增加MAC信息,之后进行加密,在添加头信息,之后交由TCP协议的下一层处理,具体步骤如下:
- 分块:每块16KB
- 压缩:可选,但必须是无损压缩
- 加MAC:对前一步的输出计算MAC(消息认证码),类似于HMAC,秘钥使用的即使握手阶段协商的秘钥。
- 加密:用握手阶段协商的秘钥对上一步输出进行加密
- 添加头部:包含以下几个字段:内容类型(8位):指上一层处理记录所用的协议;主版本(8位):如SSL3.1,主版本位3;次版本(8位):如SSL3.1,次版本是1;压缩长度(16位):指原始信息或压缩过的信息的长度
可见记录协议就是实际通信所用的协议
警报协议
通信双方任何一方发现错误时,向对方发送警报信息。若错误是致命的则立即关闭连接,终止传输,同时删除回话号、秘密和秘钥。如果错误不严重,则处理错误并继续通信。
每个警报消息有两字节,第一个字节指出错误类型,1代表一般错误,2代表致命错误;第二个字节指出详细错误
致命错误如下:
警报 | 描述 |
---|---|
无关消息(unexpected_message) | 收到不适当消息 |
坏记录(bad_record_mac) | 收到的消息没有正确的MAC |
解压失败(decompression_failure) | 解压缩功能收到错误输入 |
握手失败(handshake_failure) | 发送方无法从收到的选项中得到可接受的参数 |
非法参数(illegal_parameter) | 握手消息中字段越界或其他字段不一致 |
非致命错误:
警报 | 描述 |
---|---|
无证书(no_certificate) | 没有适当证书 |
坏证书(bad_certificate) | 证书验证失败 |
不支持的证书(unsupported_certificate) | 不支持的证书类型 |
证书吊销(certificate_revoked) | 证书已被吊销 |
证书过期(certificate_expired) | 证书已过期 |
证书未知(certificate_unknown) | 处理证书时出现未知错误 |
关闭通知(close_notify) | 表示发送方在本次连接中不再发送任何信息,双方都要发送这个消息后才关闭连接 |
关闭与恢复连接
对于关闭连接双方都要发送close_notify消息,这样才能优雅的借书连接。若有一方没有发送该信息,则连接无法恢复
从整个流程看,握手协议比较复杂与费时,所以复用或恢复连接是一个较好的选择,算法可以协商复用,若一方不同意则不能复用,另外,对于任何连接,在24小时后不得复用
题图来自unsplash:https://unsplash.com/photos/UZ3V6AV5y4o