相信大家对于 HTTPS 协议都不陌生,但是应该存在以下疑问:
- HTTPS 协议到底是如何运作的?
- HTTPS 是如何解决 HTTP 协议的不安全特性的?
- HTTPS 网站抓包为什么要信任证书?
HTTP 协议
HTTP 协议是一个 应用层 协议,通常运行在 TCP 协议之上。它是一个 明文协议
,客户端发起请求,服务端给出响应的响应。
由于网络并不是可信任的,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 中间人攻击需要手动信任攻击者的假证书