中间人攻击
服务器可以创建出一堆公钥和私钥,黑客也可以按照同样的方式,创建一对公钥和私钥,冒充自己是服务器(搅屎棍)
- 黑客自己也能生成一对公钥和私钥。生成公钥和私钥的算法是开放的,服务器能生产,黑客也能生成
- 客户端拿到
pub2
之后,无法区分pub2
是否是服务器的,于是就拿着pub2
就对key
进行加密了 - 随后信息到达黑客之后,就使用
pri2
对上述数据进行解密,然后黑客就拿到了key
- 黑客继续使用从服务器拿到的
pub1
对key
进行加密,传给服务器· - 服务器拿到数据之后,使用
pri1
来解密,于是知道了对称密钥是key
。后续的通信,服务器和客户端之间,仍会继续使用key
作为加密的密钥。此时后续传输的各种数据就可以被黑客解密了
引入证书
针对中间人攻击,怎么解决?
最关键的一点,客户端在拿到公钥的时候,要能有办法验证,这个公钥是否是真的,而不是黑客伪造的。这就要求服务器这边,要可以提供一个“证书”
- 证书是一个结构化的数据(里面包含很多属性,最终以字符串的形式提供)
- 证书中会包含一系列的信息(服务器的主域名、公钥、证书有效期…)
证书是搭建服务器的人,要从第三方的共振机构进行申请的
证书的验证
证书里面包含:
- 服务器的域名:…
- 证书的有效时间:…
- 服务器的公钥:…
- 公正机构信息:…
- …
- 证书的签名:…(验证过程中最重要的)
证书签名
此处的签名本质上是一个经过加密的校验和
- 把证书中其他的字段通过一系列的算法(CRC、MD5 等),得到一个较短的字符串,就是校验和
- 如果两份数据内容一样,此时校验和就一定是相同的;如果校验和不同,则两份数据一定不同
颁布证书的公证机构,会在颁布证书的时候,给这个证书计算出校验和。然后公正机构会使用自己的私钥(和服务器的私钥无关),针对校验和进行加密,此时就得到了证书的签名
验证过程
客户端拿到证书之后,主要做两件事:
- 按照同样的校验和算法,把证书的其他字段都重新算一遍,得到 校验和1
- 使用系统中内置的公正机构的公钥,对证书中的签名进行解密,得到 校验和2
此时,就可以对比,这两个校验和是否一致。若一致,就说明证书是没有被修改过的,就是原版证书;若不一致,就说明证书被人篡改过了(比如黑客如果替换了自己的公钥,此时出来的校验和一定发生变化),此时客户端就能识别出来了
- 此时浏览器这边就会弹出一个告警页面,告诉用户,你访问的网站有风险,请谨慎访问!!!(可能是黑客进行了中间人攻击,也可能是证书过期了)
市面上的公正机构一共也没多少,这些公正机构都有自己的私钥,对应的公钥都包含在常见的系统中。Windows 里面就内置了大量的公钥(如果没有,也可以额外安装)
- 前面安装 fiddler 的时候,有一步操作就是在安装证书(主要就是在安装 fiddler 这边提供的公钥)
证书是为了防止黑客篡改,而不是为了避免黑客知道。黑客的系统也内置了公正机构的公钥,黑客也能进行解密
- 如果黑客直接修改公钥,不修改签名。此时,客户端验证的校验和是一定不一样的,直接就识别出来了
- 如果黑客修改公钥,也尝试重新生成签名,由于黑客不知道公正机构的密钥,所以黑客无法重新生成加密的签名。
如果黑客拿自己的私钥加密呢?客户端这边拿着公证机构的公钥也会解密失败 - 黑客能不能自己也去公证机构申请个证书?然后把自己的整数替换掉服务器的证书呢?
证书中还需要包含服务器的域名,域名是唯一的,黑客申请的证书的域名,和原服务器的域名肯定是不同的。
客户端拿到证书之后,一看域名都不一样,直接就知道证书是假的了,都不用进行校验和验证了
当然,上述的过程,所谓的安全,也不是绝对的安全。上述的安全本质上都是基于非对称加密体系。非对称加密体系也不是无懈可击的,只不过破解这样的加密体系,需要的计算量非常大,超出了现有计算机的算力上限。
随着算力的提升,尤其是量子计算机崛起,我们的算力又会大幅度提升,对现有的密码学体系就会造成重大冲击