https 中间人攻击及防御
HTTPS 也不是绝对安全的,在 HTTPS 握手的过程中,如果实施不当,还是会存在漏洞,很容被中间人攻击;
什么是中间人攻击
中间人攻击(Man-in-the-middle attack,缩写:MITM)是指攻击者与通讯的两端分别建立独立的联系,并交换其所收到的数据,使通讯的两端认为他们正在通过一个私密的连接与对方直接对话,但事实上整个会话都被攻击者完全控制。在中间人攻击中,攻击者可以拦截通讯双方的通话并插入新的内容。
如何进行中间人攻击的呢?
攻击一:SSLSniff
攻击者在网关截获 SSL 会话,替换服务器公钥证书,将公钥PKey
换成自己的公钥PKey
,欺骗客户端。客户端使用PKey
加密信息并发送会话,中间人用私钥Skey
解密客户端返回会话,从而劫持会话。同时,中间人用PKey
加密明文会话并返回服务器
过程如下:
Attacker
截获了客户端的say hello
,可以把publicKey_attacker
返回给客户端,取得客户端的信任,至此Attacker
与客户端建立了安全连接。Attacker
冒充客户端向服务器发送say hello
,至此Attacker
与服务器建立了安全连接。
这种攻击会存在一个问题会被感知到,就是Attacker
的证书是伪造的不受信任的证书,所以客户端可以确认是否需要真的连接该服务器,不过如果有内鬼的话,伪造的受信任的证书的话,就当我啥也没说;
攻击二:SSLStrip
这种攻击相对于攻击一复杂一点,但是也更加厉害,几乎可以在客户端无感知的情况下实施攻击,并且不需要伪造证书;简单来说就是这样:Attacker
在客户端与服务器建立连接时,在Attacker
与服务器之间形成 HTTPS 连接,而在客户端与Attacker
之间形成HTTP
连接,即将 SSL 层从原 HTTPS 连接中“剥离”。这样,既避免了在客户端验证证书时难以避免的弹框问题,又能够劫持 HTTP 明文数据,并同时保证客户端HTTP
数据的传输,达到欺骗服务器与客户端的效果。
过程如下:
用户在浏览器地址栏中输入网址时,多数会采用直接输入网址的方式,而忽略了传输所采用的协议。例如,在登录 gmail 过程中,大多数用户会直接在地址栏中输入www.gmail.com
,向Google
服务器发送一个 HTTP 连接请求,而不是输入https://www.gmail.com
, 向服务器发送一个HTTPS
连接请求。因此,用户通常接触到 HTTPS 的方式有两种:一种是 Web 上的连接,比如当用户在 gmail 上输入用户名和密码后,点击的登录键,将用户的用户名和密码以HTTPS
的形式POST
到服务器。另一种是通过 HTTP 的 302 状态。 当客户端向 gmail 提出 HTTP 连接请求时,gmail 服务器会返回一个REDIRECT
网址,https://www.google.com/accounts/ServiceLogin?service=mail...
,用户端在接收到这个 URL 后,将页面重定位到该网页,并请求 HTTPS 连接。 从另外一个角度讲,用户通常是通过HTTP
向服务器发起HTTPS
连接的。而HTTP
本身是以明文的形式对外传送,并不能保证数据的安全。因此,可以考虑通过对 HTTP 进行劫持,来实现对 HTTPS 劫持的目的。
- 客户端向服务器发起
HTTP
连接请求; - 中间人 MITM 监听客户端与服务器的
HTTP
数据; - 服务器返回给客户端的 HTTP 数据包被在客户端与服务器之间的中间人截获。中间人解析原 HTTP 数据包,将其中
<a href=”https://...”>
替换成<a href=”http//...”>
,将Location: https://...
替换成Location:http://..
,同时记录下所修改的 URL,并保存; - 中间人将修改后的
HTTP
数据发送给客户端; - 客户端向服务器发起
HTTP
连接请求; - 中间人计算机解析客户端的
HTTP
连接请求,并与保存文件相比较。当发现存在有已修改过的HTTP URL
时,将其替换成原HTTPS URL
,并发送给服务器; - 与服务器保持
HTTPS
连接,回到步骤 3; - 与客户端保持
HTTP
连接,回到步骤 4。
效果就是: 服务器认为 HTTPS 是安全的。对于客户端而言,由于中间人 MITM 与客户端 Client 之间是 HTTP 连接,因此并不会对证书进行认证;
HSTS:为了解决这个问题,IETF(互联网工程任务小组)引入了一个策略,叫做 HSTS (HTTP Strict Transport Security, HTTP 严格传输安全)。HSTS 的作用是强制客户端与服务端建立安全的 HTTPS 连接,而非不安全的 HTTP 连接。如果一个站点启用了 HSTS 策略,那么客户端在第一次与该站点建立连接之后,在未来的一段时间内(由一个 HTTP 头部控制,这个头部为:Strict-Transport-Security),客户端与该站点的所有连接都会直接使用 HTTPS,即使客户端访问的是 HTTP,也会直接在客户端重定向到 HTTPS 连接。
假设 https://example.com
的响应头部含有 Strict-Transport-Security: max-age=31536000; includeSubDomains
,这意味着:
- 在未来的 1 年时间里(即 31536000 秒中),只要浏览器向
example.com
或者其子域名发送请求,必须采用 HTTPS 来发起连接。即使用户在地址栏里写的是http://example.com
,那也直接重写为https://example.com
并直接发起 HTTPS 连接。 - 在接下去的一年中,如果服务器提供的 HTTPS 证书无效(不论是域名对不上还是自签名还是不在有效期内),用户都无法访问该站点。
如果站点没有启用 HSTS,用户可以忽略证书无效的警告,继续建立连接,而如果站点启用了 HSTS,那么用户即使想冒风险,浏览器也不会继续访问。
HSTS 可以很大程度上防止 SSLTrip 攻击,不过这样还是有个问题,那就是要启用 HSTS,浏览器至少要和服务器建立一次 HTTPS 连接,如果中间人一直阻止浏览器与服务器建立 HTTPS 连接,那么 HSTS 就失效了。解决这个问题有个办法,那就是将 HSTS 站点列表内置到浏览器中,这样只要浏览器离线判断该站点启用了 HSTS,就会跳过原先的 HTTP 重定向,直接发起 HTTPS 请求。
如何防御中间人攻击?
中间人攻击是一个(缺乏)相互认证的攻击;由于客户端与服务器之间在 SSL 握手的过程中缺乏相互认证而造成的漏洞
防御中间人攻击的方案通常基于以下几种技术
- 公钥基础建设 PKI,更强力的相互认证
使用 PKI 相互认证机制,客户端验证服务器,服务器验证客户端;上述两个例子中都是只验证服务器,这样就造成了 SSL 握手环节的漏洞,而如果使用相互认证的的话,基本可以保证
- 延迟测试
使用复杂加密哈希函数进行计算以造成数十秒的延迟;如果双方通常情况下都要花费 20 秒来计算,并且整个通讯花费了 60 秒计算才到达对方,这就能表明存在第三方中间人。
https 通信安全性的保证
通信过程的安全性自下而上就是这样保证的:
- 双方通信内容的安全性是靠公钥加密、私钥解密来保证的,这一安全性由非对称加密的特性,即由公钥加密的信息只能使用对应的私钥才能解开来保证。由于私钥不会传递,只有拥有者知道,所以安全性就由公钥的正确性来保证。
- 公钥由对方在通信初始所提供,但是这时很容易被中间人替换掉,为了保证公钥的正确性,所以在发送公钥的时候也会提供对应的数字证书,用于验证这个公钥是对方的而不是中间人的。那么安全性就是由数字证书的正确性来保证了。
- 数字证书是由上级 CA 签发给个人 / 组织的,上级 CA 用自己的私钥给个人证书进行签名,保证证书中的公钥不被篡改,而接受者需要用上级 CA 证书中的公钥来解密个人数字证书中的数字签名来验证证书中的公钥是否是正确的。那么安全性就是由*上级 CA 证书的正确性保证的了。*(数字签名保证了数字证书没有被篡改**)
- 但是,上级 CA 证书也是由其上级 CA 签发的,这种信任关系一直到根证书。根证书没有上级 CA 为其签名,而是自签名的,也就是说,它自身为自身签名,保证正确性。所以根证书就是这个信任链最重要的部分。如果根证书泄露的话,其签名的所有证书及使用其签名的证书所签名的证书的安全性将不复存在。现在,安全性就是靠系统根证书的私钥不被泄露或者其公钥不被篡改来保证的了。
- 根证书不应该通过网络分发,因为通过网络分发的话,可能会被中间人攻击。一般根证书都通过操作系统或者浏览器分发,在操作系统中会内置很多根证书,但是最初的操作系统也不能通过网络分发,因为中间人可以修改操作系统中的根证书。所以要保证安全只能靠最原始的方法,当面交流。硬件厂商会和证书签发机构合作,在电脑、手机等设备出厂的时候在其操作系统中内置签发机构的根证书,再将这些设备分发出去,这样,这些设备的用户就可以安全地进行信息交换了。所以,安全性就依赖于这些设备在分发到消费者手中之前不会被恶意修改来保证了。
至此,整个信任链就建立起来了,只需要有一台设备上安装了可以信任的根证书,就可以用来分发更多安全的操作系统了。之后的所有信任链都是安全的了。