Halo

A magic place for coding

0%

中间人攻击

Introduction

  之前在讨论过网络安全相关的CSRF问题,今天这篇博客我们来看另一个常见的网络攻击——中间人攻击。

A Glance of HTTPS

  在讨论中间人攻击之前,我们要先回顾一下HTTPS是怎么实现的。

  大家都知道HTTPS很安全,反正就算不了解原理,每次浏览器访问的时候都会有一个绿色的勾,看上去就很让人放心,觉得自己的数据十分安全。但真的是这样的吗?HTTPS使用了什么加密算法去保证数据的安全?

  HTTPS分为两部分,第一部分是证书验证,第二部分是数据传输

证书验证

  证书验证是HTTPS的关键所在,有如下步骤:

  1. 浏览器->服务器:服务器接收到浏览器请求后,返回自己的证书,证书里面包含公钥
  2. 浏览器:浏览器收到服务器返回的证书后,对证书的合法性进行验证,包括对域名、有效期等基本信息进行验证,同时还会验证证书来源是否合法、通过CA判断证书是否被篡改等,如果验证合法则进入下一步,否则提示用户使用HTTP(风险提示);
  3. 到这一步就完成了证书验证;

数据传输

  在完成了证书验证后,就开始数据的传输,这里就包含了两种不同的加密算法。

  1. 浏览器->服务器:浏览器生成一个随机数,然后里面上面证书中的公钥,对这个随机数进行加密,并把加密结果传输给服务器;
  2. 服务器:服务器收到这个加密的随机数后,这里采用的是非对称加密,所以服务器用自己的私钥能够解出来这个随机数;
  3. 服务器->浏览器:在服务器返回用户数据给浏览器的时候,使用随机数对内容进行对称加密
  4. 浏览器:浏览器拿到内容后,因为随机数是之前本地生成的,是本地存储的,所以可以解密传输内容。

对称加密与非对称加密

  很多人认为HTTPS的安全性就在于它使用了非对称加密。通过上面的介绍,我们知道其实在真正传输数据的时候,浏览器和服务器双方其实使用的是对称加密,只有在第一次验证完证书后,才利用非对称加密技术传递了一个随机数(这个随机数就是在后面用于对称加密的)。

  那么就会有人问,既然非对称加密安全,为什么传输数据的时候还是使用对称加密呢?有两个原因,其一,非对称加密和解密的效率远低于对称加密,所以在https大量交互及传输数据的场景下,非对称加密不太适用;其二,非对称加密是单向的,就是说只能用公钥加密,然后私钥解密,但在实际的http请求中,应该是要保证双向的数据都是受保护的。

中间人攻击

  从上面的分析可知,HTTPS数据在实际传输中是对称加密,因此它的安全性并不是在数据传输中使用了非对称加密,那么关键点在哪?我们先来看看中间人攻击利用了什么漏洞,然后再回过来指出HTTPS是如何防范中间人攻击的。

  中间人攻击的过程如下:

  1. 浏览器->中间人服务器A:浏览器向目标服务器发起请求,这里的请求是根据域名的,所以会先有一个DNS解析。现在发生了DNS劫持,比如把所有请求www.google.com的解析都指向了中间人的服务器A,所以请求实际上只打到了A,而没有到达真正的目标服务器;
  2. 中间人服务器返回自己购买的一个证书X1
  3. 浏览器:浏览器本地生成一个随机数,通过拿到的证书X1中的公钥对随机数进行加密,发送给服务端,同时这个随机数也是后面用于数据传递时对称加解密;
  4. 浏览器->中间人服务器A:浏览器的请求因为DNS劫持的缘故被打到了中间人服务器A上,服务器A上有私钥,可以解密出随机数,得到这个随机数后,服务器A可以对来自A的所有内容进行对称加解密;
  5. 浏览器->中间人服务器A:在请求数据时,浏览器利用随机数加密,服务器A拿到数据后用随机数解密,拿到用户请求的明文;
  6. 中间人服务器A->目标服务器:为了欺骗用户,让用户觉得真正在访问目标服务器,服务器A还是会去请求目标服务器,此时它与目标服务器建立了安全通道,拿到数据后,它再次利用随机数加密,返回给浏览器;
  7. 浏览器:浏览器拿到数据后用随机数解密,得到的就是来自目标服务器的数据。

  上面就是中间人攻击的主要步骤,对于浏览器来说,他并不知道中间人的存在,它会觉得一直在和目标服务器打交道,拿到的数据也是准确的。而对于中间人服务器A来说,它一直在中间搞怪,双方传输的数据都能看得一清二楚,如果用户是操作银行登录的话,用户密码就能看的一清二楚。

what is the pitfall?

  上面7个步骤中最坑的步骤就是第2步和第3步,因为当浏览器把自己的随机数用非对称加密算法交给服务器后,就说明它完全信任服务器了,所以在这之前必须验证请求的是可以信任的服务器。

  上面HTTPS过程中提到了一个证书的概念,这个才是整个HTTPS的重中之重。浏览器必须通过某种手段去验证这个证书确实来自目标服务器,才能认为请求的服务器是可靠的。那么问题就变成了如何认证证书的合法性?

How to validate the certificate?

  首先这里我们说的证书,指的是一种公钥证书,它是一种将加密密钥与网站、个人或组织等身份安全地关联起来的数字文档。分别来看它的几个要点:

  1. 加密密钥:这里的加密密钥指的是非对称加密体系中的公钥,服务器以证书的方式,把公钥传递出去,而自己保留私钥;
  2. 网站、个人或组织身份:这点非常关键,我们知否信任一个证书,很大程度上并不是取决于返回证书的网站可不可信,而是取决于返回证书的网站是不是就是我们请求的网站。所以在返回的证书中需要带上能够验证网站身份的信息,并且是权威的;
  3. 安全地关联:这是一种防篡改的手段。

  然后我们来看浏览器是怎么去验证证书的合法性的:

  1. 证书上包含域名和有效期等基本信息,浏览器可以很快速地去验证这些信息是否有效;
  2. 判断证书来源是否合法。每份签发证书都可以根据验证链查找到对应的根证书,操作系统、浏览器会在本地存储权威机构的根证书,利用本地根证书可以对对应机构签发证书完成来源验证;
  3. 通过CA服务器判断证书是否被篡改。在CA签发证书的时候,会把公钥、用途、颁发者、有效时间等信息打成一个包data,然后对这个包进行hash,得到一个hash值H1(H1=hash(data)),然后CA会使用自己的私钥对这个H1加密,得到签名Signature,这个签名就带在证书上面。浏览器验证的时候,首先从证书中获取到数字签名的加密算法,然后使用公钥对Signature解密,得到H1。另一方面,浏览器对证书中的公钥、用途、颁发者等信息也打成一个包data,然后也对这个包hash,得到一个hash值H2,最后通过对比H1和H2是否一样就能验证证书是否被篡改了。

How to prevent

  上面引入了证书校验这一步正正是解决了中间人攻击的问题。因为证书都需要CA签发,所以必须是认证过的网站所有者才拥有证书,因此非法的证书或者不属于这个网站的证书都无法通过浏览器的校验,此时浏览器就会有安全风险提示,避免了中间人攻击。

More Vernurabilities

  除了中间人攻击外,HTTPS的可靠性还依赖于本地生成并存储的随机数,因为后续数据传输的过程都是使用这个随机数做堆成加密的,因此一旦这个随机数泄露,数据也就有暴露的风险,但这个属于计算机本地的安全问题。

  同时,使用HTTPS时,数据包也是能够被抓取的,只不过数据内容是加密保护。

Summary

  在这篇博客我们简单地了解了HTTPS的工作原理,知道了HTTPS是通过加密手段提供安全的数据传输,同时也了解了中间人攻击,以及HTTPS通过证书对这类攻击进行防范。

Reference

  1. 你连HTTPS原理都不懂,还讲“中间人攻击”?
  2. DNS劫持原理?如何处理DNS劫持?
  3. Man-in-the-middle attack
  4. What Is an X.509 Certificate
  5. 浏览器如何验证HTTPS证书的合法性

Welcome to my other publishing channels