HTTPS 是如何防止中间人攻击的呢?要防止被中间人攻击,那么就要确保通信中的信息来自他声称的那个人,且没有被修改过。在现实中,有多种方式可以确定某个实体的身份,比如个人的签名 / 私章、组织的公章、甚至古时的信物。大部分情况下,只需要在信件最后盖上签上自己的名字或者盖上组织的公章,那么接收者就可以确定这封信件就来自于他所声称的那个人 / 组织。在二进制的世界中,可以使用数字签名来确保某段消息 / 某份文件确实是由他所声称的那个实体所发出来的。
在之前的文章中,我们介绍过非对称加密,其中公钥是公开的,而私钥只有拥有者知道。用私钥对某个文件 / 某段消息的散列值进行签名就像一个人亲手在信件最后签上了自己的名字一样,证明这份文件 / 这段消息确实来自私钥的拥有者(因为公钥是公开的,私钥只有拥有者知道,所以如果能用其公开的公钥解开数字签名,那就证明这条消息确实来自于他私钥的拥有者),这就可以确保消息是来自他所声称的那个实体。这样,在通信中,双方每次在写完消息之后,计算消息的散列值,并用自己的私钥加密生成数字签名,附在信件后面,接收者在收到消息和数字签名之后,先计算散列值,再使用对方的公钥解密数字签名中的散列值,进行对比,如果一致,就可以确保该消息确实是来自于对方,并且没有被篡改过。
不过有个问题,如果中间人在会话建立阶段把双方交换的真实公钥替换成自己的公钥了,那么中间人还是可以篡改消息的内容而双方并不知情。为了解决这个问题,需要找一个通信双方都信任的第三方来为双方确认身份。这就像大家都相信公证处,公证处拿着自己的公章为每一封信件都盖上了自己的章,证明这封信确实是由本人发出的,这样就算中间人可以替换掉通信双方消息的签名,也无法替换掉公证处的公章。这个公章,在二进制的世界里,就是数字证书,公证处就是 CA(数字证书认证机构)。
数字证书就是申请人将一些必要信息(包括公钥、姓名、电子邮件、有效期)等提供给 CA,CA 在通过各种手段确认申请人确实是他所声称的人之后,用自己的私钥对申请人所提供信息计算散列值进行加密,形成数字签名,附在证书最后,再将数字证书颁发给申请人,申请人就可以使用 CA 的证书向别人证明他自己的身份了。对方收到数字证书之后,只需要用 CA 的公钥解密证书最后的签名得到加密之前的散列值,再计算数字证书中信息的散列值,将两者进行对比,只要散列值一致,就证明这张数字证书是有效且未被篡改过的。