互联网的通信安全,建立在SSL/TLS协议之上。Https是现代大厂越来越关注的技术,本文带你理解Https的核心SSL/TLS协议。
1.协议作用
不使用SSL/TLS的HTTP通信,就是不加密的通信。所有信息明文传播,带来了三大风险。
- 窃听风险(eavesdropping):第三方可以获知通信内容。
- 篡改风险(tampering):第三方可以修改通信内容。
- 冒充风险(pretending):第三方可以冒充他人身份参与通信。
SSL/TLS协议是为了解决这三大风险而设计的,希望达到:
- 所有信息都是加密传播,第三方无法窃听。
- 具有校验机制,一旦被篡改,通信双方会立刻发现。
- 配备身份证书,防止身份被冒充。
2.协议历史
1994年,NetScape公司设计了SSL协议(Secure Sockets Layer)的1.0版,但是未发布。
1995年,NetScape公司发布SSL 2.0版,很快发现有严重漏洞。
1996年,SSL 3.0版问世,得到大规模应用。
1999年,互联网标准化组织ISOC接替NetScape公司,发布了SSL的升级版TLS 1.0版。
2006年和2008年,TLS进行了两次升级,分别为TLS 1.1版和TLS 1.2版。最新的变动是2011年TLS 1.2的修订版。
目前,应用最广泛的是TLS 1.0,接下来是SSL 3.0。但是,主流浏览器都已经实现了TLS 1.2的支持。
TLS 1.0通常被标示为SSL 3.1,TLS 1.1为SSL 3.2,TLS 1.2为SSL 3.3。
3.架构与分层
SSL/TLS是一个安全通信框架,上面可以承载HTTP协议或者SMTP/POP3协议等
3.1 协议内部的功能层面
SSL/TLS 协议可分为两层:
- SSL/TLS 记录协议(SSL/TLS Record Protocol),它建立在可靠的传输层协议(如 TCP)之上,为上层协议提供数据封装、压缩、加密等基本功能。
- SSL/TLS 握手协议(SSL/TLS Handshake Protocol),它建立在 SSL/TLS 记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等初始化协商功能。
3.2 协议使用方式
可以分成两种类型:
-
- SSL/TLS 单向认证:就是用户到服务器之间只存在单方面的认证,即客户端会认证服务器端身份,而服务器端不会去对客户端身份进行验证。首先,客户端发起握手请求,服务器收到握手请求后,会选择适合双方的协议版本和加密方式。然后,再将协商的结果和服务器端的公钥一起发送给客户端。客户端利用服务器端的公钥,对要发送的数据进行加密,并发送给服务器端。服务器端收到后,会用本地私钥对收到的客户端加密数据进行解密。然后,通讯双方都会使用这些数据来产生双方之间通讯的加密密钥。接下来,双方就可以开始安全通讯过程了。
-
- SSL/TLS 双向认证:就是双方都会互相认证,也就是两者之间将会交换证书。基本的过程和单向认证完全一样,只是在协商阶段多了几个步骤。在服务器端将协商的结果和服务器端的公钥一起发送给客户端后,会请求客户端的证书,客户端则会将证书发送给服务器端。然后,在客户端给服务器端发送加密数据后,客户端会将私钥生成的数字签名发送给服务器端。而服务器端则会用客户端证书中的公钥来验证数字签名的合法性。建立握手之后过程则和单向通讯完全保持一致。
4.基本的运行过程
SSL/TLS协议的基本思路是采用公钥加密法,也就是说,客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密。
但是,这里有两个问题。
(1)如何保证公钥不被篡改?
解决方法:将公钥放在数字证书中。只要证书是可信的,公钥就是可信的。
(2)公钥加密计算量太大,如何减少耗用的时间?
解决方法:每一次对话(session),客户端和服务器端都生成一个"对话密钥"(session key),用它来加密信息。由于"对话密钥"是对称加密,所以运算速度非常快,而服务器公钥只用于加密"对话密钥"本身,这样就减少了加密运算的消耗时间。
因此,SSL/TLS协议的基本过程是这样的:
- (1) 客户端向服务器端索要并验证公钥。
- (2) 双方协商生成"对话密钥"。
- (3) 双方采用"对话密钥"进行加密通信。
上面过程的前两步,又称为"握手阶段"(handshake)。
5.SSL协议握手过程
假定客户端叫 樱木,服务器叫 流川枫,整个握手过程:
- 第一步,樱木 向 流川枫 发送:
1. 客户端可以支持的SSL最高版本号
2.一个客户端生成的随机数(Client random,一个用于生成主秘密的32字节的随机数)
3. 客户端支持的加密方法
4. 一个确定会话的会话ID
5. 一个客户端可以支持的密码套件列表(密码套件格式:每个套件都以“SSL”开头,紧跟着的是密钥交换算法。用“With”这个词把密钥交换算法、加密算法、散列算法分开,例如:SSL_DHE_RSA_WITH_DES_CBC_SHA,表示把DHE_RSA(带有RSA数字签名的暂时Diffie-HellMan)定义为密钥交换算法;把DES_CBC定义为加密算法;把SHA定义为散列算法)
6. 一个客户端可以支持的压缩算法列表
-
第二步,流川枫确认双方使用的加密方法,并给出数字证书、以及一个服务器生成的随机数(Server random)。
发送内容:
1.一个SSL版本号:取客户端支持的最高版本号和服务端支持的最高版本号中的较低者。
2.一个用于生成主秘密的32字节的随机数。(客户端一个、服务端一个)
3.会话ID
4.从客户端的密码套件列表中选择的一个密码套件(SSL中密钥交换算法有6种:无效(没有密钥交换)、RSA、匿名Diffie-Hellman、暂时Diffie-Hellman、固定Diffie-Hellman、Fortezza。)
5.从客户端的压缩方法的列表中选择的压缩方法
至此:樱木(客户端服务端)知道了下列内容
SSL版本
密钥交换算法、散列算法和加密算法
压缩方法
有关密钥生成的两个随机数
- 第三步,樱木确认数字证书有效,然后生成一个新的随机数(Premaster secret),并使用数字证书中的公钥,加密这个随机数,发给流川枫。
- 第四步,流川枫使用自己的私钥,获取樱木发来的随机数(即Premaster secret)。
- 第五步,樱木和流川枫根据约定的加密方法,使用前面的三个随机数,生成"对话密钥"(session key),用来加密接下来的整个对话过程。
6.私钥的作用
握手阶段有三点需要注意
- (1)生成对话密钥一共需要三个随机数。
- (2)握手之后的对话使用**"对话密钥"加密(对称加密)**,服务器的公钥和私钥只用于加密和解密"对话密钥"(非对称加密),无其他作用。
- (3)服务器公钥放在服务器的数字证书之中。
从上面第二点可知,整个对话过程中(握手阶段和其后的对话),服务器的公钥和私钥只需要用到一次。
例子:
某些客户(比如银行)想要使用外部CDN,加快自家网站的访问速度,但是出于安全考虑,不能把私钥交给CDN服务商。这时,完全可以把私钥留在自家服务器,只用来解密对话密钥,其他步骤都让CDN服务商去完成。
7.密钥交换算法
密钥交换算法一般常用的有RSA和DH
**整个握手阶段都不加密(也没法加密),都是明文的。**因此,如果有人窃听通信,他可以知道双方选择的加密方法,以及三个随机数中的两个。
整个通话的安全,只取决于**第三个随机数(Premaster secret)**能不能被破解。
虽然理论上,只要服务器的公钥足够长(比如2048位),那么Premaster secret可以保证不被破解。但是为了足够安全,我们可以考虑把握手阶段的算法从默认的RSA算法,改为Diffie-Hellman算法(简称DH算法)。
DH算法的详细介绍- blog.csdn.net/fw0124/arti…
8.session的恢复
握手阶段用来建立SSL连接。如果出于某种原因,对话中断,就需要重新握手。
这时有两种方法可以恢复原来的session: 一种叫做session ID,另一种叫做session ticket。
session ID的思想很简单,就是每一次对话都有一个编号(session ID)。如果对话中断,下次重连的时候,只要客户端给出这个编号,且服务器有这个编号的记录,双方就可以重新使用已有的"对话密钥",而不必重新生成一把。
上图中,客户端给出session ID,服务器确认该编号存在,双方就不再进行握手阶段剩余的步骤,而直接用已有的对话密钥进行加密通信。
session ID是目前所有浏览器都支持的方法,但是它的缺点在于session ID往往只保留在一台服务器上。所以,如果客户端的请求发到另一台服务器,就无法恢复对话。session ticket就是为了解决这个问题而诞生的,目前只有Firefox和Chrome浏览器支持。
上图中,客户端不再发送session ID,而是发送一个服务器在上一次对话中发送过来的session ticket。这个session ticket是加密的,只有服务器才能解密,其中包括本次对话的主要信息,比如对话密钥和加密方法。当服务器收到session ticket以后,解密后就不必重新生成对话密钥了。