中间人攻击


中间人攻击

在 http 数据提交给 TCP 层之后,会经过用户电脑、路由器、运营商、服务器,这中间每一个环节,都不是安全的

一句话就是:在 http 传输过程中容易被中间人窃取、伪造、篡改,这种攻击方式称为中间人攻击

那怎么让数据可以更安全的传输呢?

就是使用 https ,利用 https 安全层对数据进行加解密操作,以保证数据安全。

关于 https性能优化、版本、优缺点、SSL/TLS、握手(RSA、TLS1.2、TLS1.3)三个版本及优化等等,文章太长这里就不展开了,可以看我另一篇文章有详细介绍

那么 https 是如何对数据加解密的呢?这要先说一下它的算法

对称加密算法

就是加密和解密使用同一个密钥。如AES、DES。加解密过程:

  1. 浏览器给服务器并发送一个随机数client-random加密套件(一个支持的加密方法列表)
  2. 服务器生成给浏览器返回另一个随机数server-random加密套件
  3. 两边分别返回确认消息。然后两者用加密方法将两个随机数混合生成密钥,这就是通信双上加解密的密钥

有了密钥之后就可以对数据进行加密传输了

问题是client-randomserver-random都是明文的,双方如何安全的传递两个随机数和加密方法呢?直接传给客户端,那过程中就很可能被窃取,中间人还是能解密拿到数据,往下看

不对称加密算法

就是一对密钥,有公钥(public key)和私钥(private key),其中一个密钥加密后的数据,只能用另一个密钥进行解密。如RSAECDHE。加解密过程:

  1. 浏览器给服务器发送加密套件
  2. 服务器选好支持的加密方法公钥(明文) 传给浏览器
  3. 两边分别返回确认消息。然后浏览器用公钥对数据进行加密,这个密钥只能用私钥解密

这是不是看上去很完美了

其实还存在很严重的问题

  1. 使用公钥反推出私钥是非常困难,但不是做不到,随着计算机运算能力提高,非对称密钥至少要2048位才能保证安全性,这就导致加解密速度慢,效率太低
  2. 无法保证服务器发送给浏览器的数据安全。因为浏览器可以用公钥来加密,而浏览器就只能用私钥加密,公钥是明文传输的,中间人可以获取到,这样服务器端的数据安全就得不到保证了

所以!

混合加密

TLS实际用的是两种算法的混合加密通过 非对称加密算法 交换 对称加密算法 的密钥,交换完成后,再使用对称加密进行加解密传输数据。这样就保证了会话的机密性。过程如下

  1. 浏览器给服务器发送一个随机数client-random对称和非对称加密套件
  2. 服务器把另一个随机数server-random加密套件公钥传给浏览器
  3. 浏览器又生成另一个随机数pre-random,并用公钥对 pre-random 加密后传给服务器
  4. 服务器再用私钥解密,得到pre-random,并返回确认消息
  5. 这样浏览器和服务器都有三个随机数了,然后各自将三个随机数用加密方法混合生成最终的对称密钥

然后开始数据加密传输

这样即便被截持,中间人没有私钥就拿不到pre-random,就无法生成最终密钥

这样就安全了吗?

emmmm……还没

因为问题又来了,如果一开始DNS就被中间人劫持,那么请求被中间人截获,中间人把他自己的服务器公钥给了浏览器,浏览器收到公钥就把信息发给中间人了,中间人解密拿到数据,并干了一些见不得人的勾当之后,再请求实际服务器,拿到服务器公钥,再把加密处理过后的数据发给服务器

这样不知不觉间信息就被人窃取了,所以在结合对称和非对称加密的基础上,还需要服务器向浏览器证明身份,那怎么证明呢?

所以数字证书来了,往下看

如何保证数据是否被篡改?

数字证书(数字签名)

它可以帮我们验证服务器身份,而且数字证书里包含了公钥,而数字证书需要向有权威的认证机构(CA)获取授权给服务器。

相比之前就变成了

  • 服务器不直接返回公钥给浏览器,而是返回数字证书,而公钥就在数字证书中
  • 浏览器这边多了一步证书验证,验证成功才能继续后续流程

那么如何申请数字证书呢?

  • 首先,服务器准备一套公钥私钥,私钥留着自己用
  • 服务器将公钥和站点等信息提交给CA认证,这个是要钱
  • CA验证服务器提供的信息
  • 审核通过后签发认证的数字证书,包含了公钥CA信息有效时间证书序列等这些都是明文的,还有一个CA生成的签名

CA的签名过程

  • CA也有一套公钥私钥
  • CA使用摘要算法计算服务器提交的明文信息并得出信息摘要
  • 然后CA再用它的私钥和特定的算法对信息摘要加密,生成签名
  • 签名服务器公钥等信息打包放入数字证书,并返回给服务器
  • 服务器配置好证书,以后浏览器连接服务器,都先把证书发给客户端验证

摘要算法:主要用于保证信息的完整性。常见的MD5算法散列函数hash函数都属于这类算法,其特点就是单向性无法反推原文

浏览器如何验证数字证书

  • 浏览器连接服务器,都先把证书发给客户端验证
  • 使用CA公钥和声明的签名算法对CA中的签名进行解密,得到服务器的摘要内容和服务器公钥
  • 再用摘要算法对证书里的服务器公钥生成摘要,再把这个摘要和上一步得到的摘要对比
  • 然后将两个信息摘要对比,如果是一致的,就说明证书是合法的,即证明了服务器自己,否则就是非法的

证书认证又分为单向认证双向认证

单向认证:服务器发送证书,客户端验证证书
双向认证:服务器和客户端分别提供证书给对方,并互相验证对方的证书

不过大多数https服务器都是单向认证,如果服务器需要验证客户端的身份,一般通过用户名、密码、手机验证码等之类的凭证来验证。只有更高级别的要求的系统,比如大额网银转账等,就会提供双向认证的场景,来确保对客户身份提供认证性

另外在申请和使用证书的过程中,需要注意

  • 申请数字证书是不需要提供私钥的,要确保私钥永远只能由服务器掌握
  • 数字证书最核心的是CA使用它的私钥生成的数字签名
  • 内置CA对应的证书称为根证书,根证书是最权威的机构,它们自己为自己签名,这称为自签名证书

有了这些之后就安全了吗?

emmmmm…..没有

虽然不是绝对安全,但是现行架构下最安全的解决文案了,大大增加了中间人的攻击成本


文章作者: 沐华
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 沐华 !