相信大家对于HTTPS协议都不陌生,但是应该存在以下疑问:
HTTPS协议到底是如何运作的?
HTTPS是如何解决HTTP协议的不安全特性的?
HTTPS网站抓包为什么要信任证书?
HTTP协议
HTTP协议是一个应用层协议,通常运行在TCP协议之上。它是一个明文协议,客户端发起请求,服务端给出响应的响应。
对HTTP协议不太熟悉的读者可以看看这本动物书,写的很好。
HTTP权威指南(图灵出品)
作者:[美]David Gourley,[美]Brian Totty,[美]Marjorie Sayer,[美]Sailu Reddy,[美]Anshu Aggarwal
京东
由于网络并不是可信任的,HTTP协议的明文特性会存在以下风险:
-
通信数据有被窃听和被篡改的风险
- 目标网站有被冒充的风险
一般的网站可能没什么影响,但是如果是银行这种网站呢?
好在国内的银行在HTTP协议时代针对IE开发了ActiveX插件来保证安全性,这一点算是值得点赞了。
解决方案
既然HTTP协议是明文协议,如果对数据进行加密之后是否就能保证安全性了呢?
在回答这个问题之前,我们先看看比较常见的两种加密算法。
加密算法
常见的有对称加密算法和非对称加密算法。
对称加密
加密和解密使用同一个密钥。加解密效率比非对称加密高。但是密钥一旦泄露,通信就不安全了
非对称加密
存在密钥对,公钥加密私钥解密或者私钥加密公钥解密,无法通过公钥反推私钥,也无法通过私钥反推公钥。
一般情况下,使用非对称加密来传输通信所用的密钥,通信过程中采用对称加密,可以解决对称加密的安全问题以及非对称加密的性能问题。
HTTP加密通信过程
-
浏览器生成随机串A作为通信密钥
-
浏览器使用公钥将随机串A加密后得到密文B发送给服务器,这一步是安全的,因为***没有服务端私钥无法解密
-
服务端利用私钥解密出随机串A得到通信密钥
- 服务端和客户端用随机串A以及对称加密算法进行通信
这么一看似乎没有问题,毕竟***无法破解非对称加密的的内容,但是浏览器是如何得到公钥的?
有以下两种办法:
-
浏览器内置(不太可能,网站域名这么多,浏览器内置这么多公钥不现实)
- 服务器给浏览器下发(由于是明文下发,存在被窃听和篡改风险,也就是著名的中间人***)
中间人***
-
浏览器请求服务器获取公钥
-
中间人劫持了服务器的公钥,保存在自己手里
-
中间人生成一对密钥对,把伪造的公钥下发给浏览器
-
浏览器使用伪造的公钥和中间人通信
- 中间人和服务器进行通信
由于浏览器使用了伪造的公钥进行通信,所以通信过程是不可靠的
需要解决的问题
只要保证浏览器得到的公钥是目标网站的公钥即可保证通信安全,那么问题来了,如何在不可靠的网络上安全的传输公钥呢?
这就是HTTPS协议需要解决的问题
HTTPS协议
HTTPS协议涉及到的知识很多,本文只关注密钥安全交换部分,这也是HTTPS协议的精华。
HTTPS协议引入了CA和数字证书的概念。
数字证书
包含签发机构、有效期、申请人公钥、证书所有者、证书签名算法、证书指纹以及指纹算法等信息。
CA
数字证书签发机构,权威CA是受操作系统信任的,安装操作系统就会内置。
数字签名
用Hash算法对数据进行计算得到Hash值,利用私钥对该Hash加密得到签名。
只有匹配的公钥才能解密出签名,来保证签名是本人私钥签发的
证书签发过程
-
网站生成密钥对,将私钥自己保存,公钥和网站域名等信息提交给CA
-
CA把证书签发机构(也就是自己)、证书有效期、网站的公钥、网站域名等信息以明文形式写入到一个文本文件
-
CA选择一个指纹算法(一般为hash算法)计算文本文件的内容得到指纹,用CA的私钥对指纹和指纹算法进行加密得到数字签名,签名算法包含在证书的明文部分
-
CA把明文证书、指纹、指纹算法、数字签名等信息打包在一起得到证书下发给服务器
- 此时服务器拥有了权威CA颁发的数字证书以及自己的私钥
证书验证过程
-
浏览器是如何验证网站的有效性的呢?
-
浏览器以HTTPS协议请求服务器的443端口
-
服务器下发自己的数字证书给浏览器(明文)
-
浏览器先校验CA、有效期、域名是否有效,如果无效,则终止连接(服务器此时不可信任)
-
如果有效,则从操作系统取出证书颁发机构的公钥,根据签名算法对数字签名解密得到证书指纹和指纹算法
-
浏览器用解密得到的指纹算法计算证书的指纹,与解密得到的指纹进行比对,如果一致,证书有效,公钥也安全拿到了
- 浏览器此时已经和真实的服务器进行通信了,中间人无法得知通信内容,因为中间人没有网站私钥
问题是如何解决的
***冒充CA给了一个假证书给浏览器
浏览器通过CA名称从操作系统取出CA公钥时对数字签名进行解密,发现解密失败,证明这个CA签名用的私钥和操作系统内置的不是一对,就发现了伪造
***篡改了证书中的网站公钥
证书中的网站公钥可以被篡改,但是数字签名是CA私钥计算出来的,***无法计算数字签名,浏览器用内置的CA公钥对数字签名解密时就会发现指纹不匹配了,这也发现了伪造
***也能正常获取网站公钥
的确,***自己通过浏览器访问网站时也能得到公钥,这个公钥跟正常用户的公钥是一致的。
但是每个客户端和服务器通信使用的对称密钥都是临时生成且随机的,***只能知道自己的随机密钥,但是不知道其他的随机密钥
综上,浏览器通过操作系统内置权威CA公钥的方式解决了网站公钥下发问题。
HTTPS中间人***
HTTPS从协议上解决了HTTP时代的中间人***问题,但是HTTPS在用户主动信任了伪造证书的时候也会发生中间人***(比如早期的12306需要手动信任证书),HTTPS中间人***流程如下:
-
客户端用HTTPS连接服务器的443端口
-
服务器下发自己的数字证书给客户端
-
***劫持了服务器的真实证书,并伪造了一个假的证书给浏览器
-
浏览器可以发现得到的网站证书是假的,但是浏览器选择信任
-
浏览器生成随机对称密钥A,用伪造的证书中的公钥加密发往服务器
-
***同样可以劫持这个请求,得到浏览器的对称密钥A,从而能够窃听或者篡改通信数据
-
***利用服务器的真实公钥将客户端的对称密钥A加密发往服务器
-
服务器利用私钥解密这个对称密钥A之后与***通信
-
***利用对称密钥A解密服务器的数据,篡改之后利用对称密钥A加密发给客户端
- 客户端收到的数据已经是不安全的了
以上就是HTTPS中间人***的原理,这也就是HTTPS抓包为什么要信任证书的原因。
总结
-
操作系统内置权威CA公钥来保证数字签名以及数字证书的安全性
- 实施HTTPS中间人***需要手动信任***者的假证书