HTTPS是什么
我们知道HTTP是明文传输的,恶意的中间人和窃听者通过截取用户发送的网络数据包可以拿到用户的敏感信息。尤其是涉及网上交易,银行转账等操作更是危害极大。
HTTPS的核心是SSL/TLS安全协议层,该层位于应用层和传输层之间,TLS对应用层数据加密后再向下交给传输层,以解决HTTP安全传输的问题。
下面我们就一起来梳理一下TLS在背后做了哪些事情,为我们的互联网行业保驾护航。
身份验证
发送方与接收方在决定数据传输之前,第一步要做的必然是互相确认对方的身份。TLS使用数字证书帮助确认证书持有者的身份。
证书
证书是一数字形式的身份证明,通常由CA进行颁发。证书中包含了证书持有者的信息,有效期,公钥,序列号,以及证书颁发者的数字签名。
CA
CA(Certificate Authority),数字证书认证机构是负责发放和管理数字证书的权威机构,并作为电子商务交易中受信任的第三方,承担公钥体系中公钥的合法性检验的责任。
CA的作用可以用公安局来做个类比,负责给公民颁发居民身份证,身份证上的信息都是公安局签字确认过的,具有权威性。
数字签名
数字签名是非对称加密技术的另一项应用。它的原理非常简单:公私钥是成对使用的,使用私钥加密的密文,只能使用公钥来解密。因为私钥只有特定服务器才知道,所以如果公钥可以解密用私钥加密的密文,必然证明是该服务器发送的。私钥用来数字签名,表明报文是特定服务器发送的;公钥用来验证数字签名。
数字签名是使用私钥加密的校验和。将数字签名附加到报文上,一并发给接收方。
数字签名的作用:
- 证明是作者编写了这条报文;
- 可以防止报文被篡改。
描述一下整个身份验证的过程:
- 客户端向服务器发起请求
- 服务器将CA发给自己的证书发送给客户端
- 客户端在本机查找该CA是否在本机的CA列表中
- 如果存在,客户端使用该CA的公钥对该证书上的CA数字签名进行验证
- 如果验证通过,说明该证书确实是CA颁发的。
- 客户端查看证书是否在有效期,证书上的信息是否与当前访问的域名一致。
- 如果确认一致,则证明该证书属于该服务器所有。
加密
TLS需要解决的问题是安全地交换对称密钥,使用对称密钥进行数据的加解密。
加密有两种主要的技术:对称密钥加密和公开密钥加密。 这两种加密技术,TLS都在使用。
对称密钥
在对称密钥加密中,密钥既用于加密也用于解密。消息交换的双方需要同时知道该密钥。对称密钥加密常用于大数据量的加解密,相比非对称密钥加密,它的加密速度要快得多。常见的对称密钥加密算法有DES
,3-DES
,RC2
,RC4
,和AES
。
公开密钥加密
公开密钥加密是一组密钥对,由复杂的数学运算得出。其中一个密钥对外公开称之为公钥,通常密钥持有者让CA把自己的公钥写到证书中对外发布。另一把密钥由持有者秘密保存。两把密钥一起协作,一把用来加密,另一把用来解密:如果公钥用来加密,那么只有对应的私钥能解密;如果私钥用来加密,同样只有对应的公钥才能解密。这种特殊的关系使得公开密钥加密有两种重要的应用。首先,任何一个取得了服务器公钥的人,都可以用该公钥加密数据,同时只有该服务器私钥的拥有者才可以进行解密。其次,如果服务器使用私钥加密数据,那么任何取得该服务器公钥的人都可以对服务器发送的数据进行解密。这也是数字签名的实现基础。最常见的算法是RSA
。
加密技术 | 优点 | 缺点 |
---|---|---|
对称密钥 | 加解密速度快,性能好 | 密钥交换有泄露风险 |
公开密钥 | 不存在密钥交换窃取的风险;可以用作签名验证身份 | 计算复杂,性能差 |
TLS使用公钥加密对服务器进行身份验证后,在客户端和服务器之间商定对称密钥。随后使用商定的对称密钥加密会话过程中的大量数据。这种方案既利用公钥加密解决了身份验证和密钥交换的问题,又结合了对称密钥加密大量数据速度快的优点。
安全会话建立的完整过程
以上我们已经对TLS的功能和实现方式有了一个初步的了解。接下来,我们将对安全会话建立的细节做一个详细的介绍。
整个安全会话的建立,TLS是以握手的过程来协商的,具体过程下图所示:
可以看到握手协议通过一系列的有序的消息协商数据会话所需的安全参数。
客户端先发送消息启动握手
Client Hello
客户端向服务器发送Client Hello
以发起会话,Client Hello
包含以下信息:
- 版本号。客户端可以支持的最高版本的协议。
- 随机数。长度为32字节的随机数。由4字节的客户端时间加28字节的随机数组成。
- sessionID。sessionID用来恢复之前的会话。恢复之前的会话很有必要,因为创建新的安全会话,需处理器进行密集的计算得到会话密钥。通过sessionID恢复已有的会话可以避免此问题。
-
加密套装。客户端可以支持的加密套装列表。例如TLS_RSA_WITH_DES_CBC_SHA,
TLS
是协议的版本,RSA
是密钥交换的非对称加密算法,DES_CBC
是对称加密算法,SHA
是散列方法。 - 压缩算法。客户端支持的压缩算法。
如下是一个 Client Hello消息的示例:
ClientVersion 3,1
ClientRandom[32]
SessionID: None (new session)
Suggested Cipher Suites:
TLS_RSA_WITH_3DES_EDE_CBC_SHA
TLS_RSA_WITH_DES_CBC_SHA
Suggested Compression Algorithm: NONE
服务器响应
服务器收到客户端的hello消息后,同样以hello消息应答:
Server Hello
服务器向客户端发送Server Hello
,该消息包括以下内容:
- 版本号。
-
随机数。服务器端随机数,由服务器时间+随机数组成。与客户端随机数一起生成
master key
。master key
用来生成会话密钥。 -
sessionID。用来恢复会话。有三种情况:
- 新sessionID。客户端没有指明sessionID,服务器返回一个新的sessionID。如果客户端指明了sessionID,但是服务器无法恢复对应的会话,也会重新生成一个sessionID。
- 恢复的sessionID。客户端指明要恢复的sessionID,同时服务器可以恢复该会话。
- 无。是新的会话,但服务器不希望将来恢复该会话,所以不返回sessionID。
- 加密套装。服务器选择一个服务器和客户端都支持的最强的加密套装。如果没有彼此都支持的加密套装,那么会结束会话,发送一个握手失败的警告。
- 压缩算法。指定选用的压缩算法。
下面是一个Server Hello
消息的例子:
Version 3,1
ServerRandom[32]
SessionID: bd608869f0c629767ea7e3ebf7a63bdcffb0ef58b1b941e6b0c044acb6820a77
Use Cipher Suite:
TLS_RSA_WITH_3DES_EDE_CBC_SHA
Compression Algorithm: NONE
Server Certificate
服务器向客户端发送证书。服务器证书包含了服务器的公钥。客户端使用服务器公钥验证服务器的身份,对premaster secret
加密。
客户端还会检查证书上声明的服务器名字。该名字必须与客户端正在访问的服务器名称匹配。例如,用户在浏览器中输如daojia.com
,那么该证书中的服务器名必须是daojia.com
或*.daojia.com
。如果两者不匹配,浏览器会给用户警告。
Server Key Exchange
可选项,服务器创建并向客户端发送一个暂时的密钥。该密钥可用于加密Client Key Exchange
消息。该步骤只有在公钥算法没提供必要的密钥生成元素时才需要,例如当服务器证书中没有公钥时。
Client Certificate Request
可选项,当服务器需要客户端提要身份证明时需要。该步骤适用于那些在提供敏感信息之前需要客户端验证自己身份的网站(例如银行站点)。
Server Hello Done
该信息表示服务器响应完成了,正在等待客户端响应。
客户端响应
服务器回复结束,客户端开始应答,应答消息如下:
Client Certificate
如果服务器向客户端请求证书,客户端需要发送自己的证书给服务器,以验证自己的身份。客户端证书中有客户端的公钥。
Client Key Exchange
客户端根据hello消息中发送的随机数计算出premaster secret
,使用服务器公钥对其加密后发送给服务器。
premaster secret
非常重要,因为客户端和服务器需要用它和前边的随机数,在本地独立计算master secret
,然后基于master secret
生成会话密钥,会话密钥就是安全传输时数据加密的对称密钥。
Certificate Verify
客户端使用私钥对目前为止所有的消息进行hash计算后进行签名。接收者使用签名者的公钥验证签名,确保它是客户端私钥签的名。只有当服务器请求客户端证书时才需要发送该消息。
Change Cipher Spec
该消息通知服务器此后的所有信息都将使用商定的密钥和算法进行加密。
Client Finished
该消息是先前的握手消息的加密校验和。使用hash函数计算所有握手消息的hash值,然后使用会话密钥进行加密后作为该消息的内容。
服务器响应
Change Cipher Spec Message
该消息通知客户端服务器将使用刚刚协商的密钥加密数据。
Server Finished
与Client Finished
类似,该消息是整个握手消息的hash值,hash值使用会话密钥加密处理。如果客户端能成功解密和验证包含的hash值,那么可以证明握手是成功的,客户端计算出的密钥和服务器计算出来密钥匹配。
服务器响应完成后,整个握手环节结束。一切正常的话,安全会话建立成功,https安全连接建立成功,客户端和服务器接下来可以安全地传输应用层数据了。
完整的握手过程描述:
- 客户端向服务器发送
Client hello
,向服务器发送客户端随机数和支持的加密工具。 - 服务器发送
Server hello
响应客户端,向客户端发送服务器随机数。 - 服务器将证书发送给客户端,有的服务器还可能请求客户端证书。
- 如果服务器请求客户端证书,客户端需要发送证书给服务器。
- 客户端创建随机的
pre-master secret
,使用服务器证书中提供的公钥进行加密后,发送给服务器。 - 服务器收到
pre-master secret
。客户端和服务器基于pre-master secret
独立生成master key
和 会话密钥。 - 客户端发送
Change cipher spec
通知服务器自己接下来要使用两边协商好的会话密钥加密数据了。客户端还需要发送Client finished
消息。 - 服务器收到
Change cipher spec
后,开始使用会话密钥对数据加密。服务器发送Server finished
消息给客户端。 - 至此通信双方可以使用建立的安全通道进行数据传输了。两边传送的所有信息都是经过会话密钥加密过的。
如何避免多次繁复的握手过程
如果每次https连接都要进行这么长的协商过程效率太低,因此tls支持基于sessionID保存会话,以便下次访问时快速恢复会话。
在完整的安全会话协商过程中,服务器向客户端发送了一个sessionID。随后,客户端在ClientHello消息中携带sessionID,这意味着客户端还记得之前与服务器商定的加密套装和密钥。如果服务器也记得的话,会在ServerHello消息中携带sessionID。
简化的过程如下:
Client Server
ClientHello -------->
ServerHello
[ChangeCipherSpec]
<-------- Finished
[ChangeCipherSpec]
Finished -------->
Application Data <-------> Application Data
握手过程描述:
- 客户端向服务器发送
Client hello
消息,不过消息中带上需要恢复的会话的sessionID。 - 服务器查找自己的缓存,如果找到了匹配的sessionID,并且可以恢复,则向客户端发送带有sessionID的
Server hello
消息。 - 客户端和服务器互相交换
Change cipher spec
消息,并且发送Client finished
和Server finished
。 - 客户端和服务器恢复安全会话。
通常浏览器打开HTTPS连接时需要完整的握手过程,随后对同一个服务器的请求进行快速握手。服务器通常15s后会关闭非活动状态的连接,但是会话信息一般保存的时间很久(数小时甚至几天)。
总结
https协议解决安全传输的核心是TLS协议。TLS在解决安全传输时主要处理的问题就是身份识别和密钥交换。这两个问题的解决依赖于公开密钥加密技术。以公开密钥加密技术为基础的数字证书系统是互联网安全传输的基石,是信任链的根基。
啰啰嗦嗦写了很多,目的还是希望能把细节交待的更清楚,能把一些生涩的术语讲的相对易懂一些,如果大家还是有些地方看的不清楚,可以在留言互动。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。