https详解

https详解
左杰这篇文章拖了很久了,今天终于有时间来更新了。HTTPS一直想写,但又不敢写,一来是最近时间不是很多,二来是觉得自己才疏学浅,HTTPS向下可探索的内容很多,自己才略知一二,仍然需要不断学习。
1. HTTP存在的问题
- HTTP报文使用明文方式发送,很有可能被第三方窃听
- HTTP报文可能被第三方截取后修改通信内容,接收方没有办法发现报文内容的修改
- HTTP存在认证的问题,第三方可以冒充他人参与通信
因此,我们使用HTTP传输的内容很容易被中间人窃听、冒充和篡改。具体点说,将HTTP数据提交给TCP层后,数据会经过用户电脑、WIFI路由器、运营商和目标服务器。在这中间的每个环节中,数据都有可能被窃取或者篡改。比如电脑上安装的恶意软件可以修改和篡改HTTP请求的内容,或者连接上WIFI钓鱼路由器,数据也会被黑客抓取或修改……
2. HTTPS简介
鉴于HTTP的明文传输和一些其他的问题使得传输过程毫无安全性可言,制约了网上购物、在线支付等一些列场景应用,于是倒逼着我们引入了加密方案。
从HTTP协议栈的层面来看,我们可以在TCP和HTTP之间插入一个安全层,所有经过安全层的数据都会被加密或者解密。
HTTPS全称呼又叫做超文本传输安全协议,它是基于HTTP的,安全层使用TLS/SSL进行数据加密和解密,并且还提供了一种校验机制,信息一旦被篡改。通信双方立马会发现。它还配备了身份证书,用来防止身份被冒充的情况出现。
3. TLS握手过程(简单版)
- 客户端向服务器发起请求,请求包含使用的协议版本号、本地生成的一个随机数、以及客户端支持的加密算法。
- 服务器收到请求后,确认双方使用的加密算法、给出服务器的数字证书、以及服务器生成的一个随机整数。
- 客户端确认数字证书有效之后,生成一个新的随机数,并使用数字证书中的公钥,加密这个随机数,发送给服务器。并且还会提供一个前面所有内容的hash值,来供服务器校验。
- 服务器使用自己的私钥,来解密客户端发来的随机数,并提供前面所有内容的hash值供客户端校验。
- 客户端和服务器根据约定的加密算法使用前面的三个随机数,生成会话密钥,以后的通信过程都使用这个密钥来加密信息。
4. 加密算法
4.1 对称加密
所谓对称加密也就是指加密和解密用的是相同的密钥。使用对称加密的方式实现HTTPS大致过程如下:
- 客户端向服务器发起请求,请求包含使用的协议和版本号、本地生成的一个随机数
client-random
、以及客户端加密套件列表。加密套件列表也就是客户端支持多少种加密方法的列表。 - 务器收到请求后,从加密套件列表中选取一个加密套件,然后生成一个
service-random
。把service-random
和选择的加密套件返回给客户端。 - 客户端和服务器使用相同的方法将
client-random
和service-random
混合起来生成一个密钥master-secret
,随后双方就可以使用master-secret
进行加密传输了。
因为传输client-random
和service-random
的过程是明文的,所以中间人可以拿到协商的加密套件和双方的随机数来合成密钥,一旦秘钥被其他人获取到,那么整个加密过程就毫无作用了。 这就要用到非对称加密的方法。
4.2 非对称加密
非对称加密的方法是,我们拥有两个秘钥,一个是公钥,一个是私钥。公钥是公开的,私钥是保密的。用私钥加密的数据,只有对应的公钥才能解密,用公钥加密的数据,只有对应的私钥才能解密。我们可以将公钥公布出去,任何想和我们通信的客户, 都可以使用我们提供的公钥对数据进行加密,而私钥只有服务器知道,不对任何人公开。这样一来,即使黑客截取到了数据和公钥,也无法使用公钥来解密。大致过程如下:
使用非对称加密,就能保证客户端发送给服务器的数据是安全的了,不过这种方式依然存在一些很严重的问题:
- 非对称加密的效率太低:加密的过程很慢。如果每次都是用非对称加密的方式,会导致请求的时间变长。
- 无法保证服务器发送给浏览器的数据安全:黑客可以截取服务端发送来公钥从而解密私钥加密的信息。
- 中间人攻击:黑客截取服务端发送给客户端的公钥和数据后,发送自己的公钥给客户端,然后用自己的私钥解密客户端加密的信息。代理转发给服务器。这样通信双方的信息就被窃取了。
4.3 对称加密结合非对称加密
改造后的流程大致是这样的:
- 客户端首先向服务器发送对称加密套件列表、非对称加密套件列表、协议版本号、
client-random
。 - 服务器保存
client-random
,生成随机数service-random
,然后向服务器发送选择的加密和非加密的套件、service-random
和公钥。 - 客户端保存公钥,通信双方使用
client-random
和service-random
计算出pre-master
,然后客户端使用pre-master加密发送数据给服务器。 - 服务器用自己的私钥解密
pre-master
加密的信息
因为pre-master
都是通信双方在本地生成的,黑客获取不到,所以上面非对称加密的的前两个问题便不存在了。但第三个问题还没有解决,这就需要看接下来的数字证书了。
5. 数字证书的申请与验证
第三个问题本质上是要实现这样一个额外功能:服务器要让客户端知道当前公钥和信息是我发送的,证明我就是我。
因此HTTPS引入了有公信力的认证中心,这个权威机构称为CA(Certificate Authority),颁发的证书称为数字证书。对于浏览器来说,数字证书的作用有两个:
- 通过数字证书确认服务器的身份
- 数字证书中包含了服务器公钥
包含数字证书的HTTPS流程大致如下:
5.1 如何申请数字证书
某个机构(比如掘金)要向某个权威机构申请数字证书,通常流程包含以下几步:
- 掘金准备一套公钥和私钥,私钥自己服务器留存
- 掘金向CA机构提交公钥、公司、站点等信息等待认证,这个过程可能收费
- CA通过线上、线下等多种渠道验证掘金提供信息的真实性。比如公司是否存在、企业是否合法、域名是否归属该企业等。
- 信息审核通过后,CA向掘金签发认证的数字证书,包含了掘金的公钥、组织信息、有效时间、证书序列号等原始信息,这些都是明文的。同时包含了一个CA生成的签名。
证书主要包含:掘金的原始信息+CA签名。数字签名生成:CA使用hash算法计算极客时间提交的明文信息,得出信息摘要,然后使用CA的私钥对信息摘要进行加密,生成了数字签名。
5.2 浏览器如何验证数字证书
接收方收到数字证书后,客户端会读取证书中的明文信息,然后使用CA签名相同的hash算法来计算原始信息生成信息摘要A,然后再利用对应CA的公钥对数字签名进行解密得到信息摘要B;对比信息摘要A和信息摘要B,如果一致就证明证书是合法的。同时浏览器还会验证证书相关的域名、有效时间等信息。
这就相当于验证了CA是谁,有的CA可能比较小众,客户端不知道该不该信任它,于是就会继续查找给这个CA颁布证书的CA,再以同样的方式验证上级CA的可靠性。通常情况下,操作系统中会内置信任的顶级CA的证书信息(包含公钥),如果这个CA链中没有找到浏览器内置的顶级CA,也会被判定非法。
关于这里的hash问题,初学HTTPS的时候一直觉得多余,把hash过程去掉也能保证证书没有被篡改。后来了解到更多的是性能问题,前面我们已经说了非对称加密效率较差,证书信息一般较长,比较耗时。而hash后得到的是固定长度的信息(比如用md5算法hash后可以得到固定的128位的值),这样加解密就快很多。当然也有安全上的原因,这部分内容相对深一些,感兴趣的可以看这篇解答:crypto.stackexchange.com/a/12780 更多内容可见彻底搞懂HTTPS的加密原理