前言
在HTTPS中,有一些密码学相关的概念,比如**、签名、证书等。弄清楚这些概念对于理解为什么HTTPS是安全的以及HTTPS的通信过程会有很大帮助,这就本文的目的。
公钥和私钥
公钥和私钥是非对称密码学中的概念。他们的特点是用公钥加密的密文只能用私钥解密,用私钥加密的密文只能用公钥解密。在通信过程中,私钥由服务器持有,不可外泄,公钥则通过HTTP发送给客户端。服务器发送经过私钥加密的密文给客户端,客户端可以通过公钥解开密文;客户端发送经过公钥加密的密文给服务器,服务器通过私钥解开密文。这个过程如下图所示↓
但是这样会有一个问题。中间商可以冒充服务器篡改公钥,如下图↓
为了防止中间商篡改公钥,需要用到数字证书,在讲数字证书之前还需要先了解一下数字签名。
数字签名
数字签名是个什么东西呢?它是信息的指纹。但是这不是重点,重点是数字签名的生成过程。数字签名的生成有两个步骤:
- 对明文进行哈希,得到一串哈希值;
- 对第一步得到的哈希值用私钥加密。
这里要特别注意,在数字证书中对哈希值进行加密的私钥是谁的?答案是CA认证机构的私钥。切记!切记!不明白不要紧,到后面就明白了。网上很多文章都对HTTPS中的数字签名有误解,大家一定要注意搞清楚,数字签名是先进行哈希,然后用CA的私钥加密,否则不可能明白为什么数字签名能防止中间商篡改公钥。
那么数字签名是如何使用的呢?其实看一张图就明白了。数字签名会随着内容一起被发送出去,接收方首先用公钥解密数字签名得到哈希值h1,然后对内容用同样的算法计算哈希值h2,如果h1=h2,那么说明内容没有被串改过。
然而这个过程也存在风险,如果中间商篡改了公钥,那么他就可以伪造数字签名,一样完蛋。如下图所示↓
所以问题的关键就是如何确保客户端接收到的公钥是真正的服务器的公钥,而不是中间商的公钥。这就需要用到数字证书了。
数字证书
数字证书包含两部分内容:
- 服务器信息
- 数字签名
这里的服务器信息中就包含了服务器的公钥,当然还有一些其他信息,比如证书名称、发布机构、有限期、哈希算法等。数字签名就是对服务器信息进行哈希,然后用CA认证中心的私钥加密的结果。
这里特别强调数字签名是用CA认证中心的私钥加密的,因为这样才能防止中间商串改公钥。这里还有一点需要注意,那就是操作系统会自动安装CA认证中心的公钥,所以,每个客户端都默认有CA认证中心的公钥。
如果中间商想伪造数字证书,篡改数字证书中的公钥,由于中间商没有CA认证中心的私钥,无法伪造数字签名,于是也就无法伪造数字证书了。
但是这样就万无一失了吗?并不是,如果中间商也在CA认证中心注册了数字证书,并且用这个合法的数字证书替换了服务器的数字证书,还是会完蛋。但这就不是我们该操心的问题了,这是CA认证中心该考虑的问题,应该给什么人发证书,拒绝给什么人发证书。只有CA认证中心能够区分好人和坏人,我们才是安全的。
其实到最后就是客户端把对服务器的信任委托给了CA认证中心,因为服务器是不一定可信的,那就创造一个相对一定可信的第三方。区块链做的事是把对权威的信任分发给许多人,赌的是不可能大家同时不靠谱。这个社会啊,只要有人存在,就有信任问题。
加密通信过程
真正的HTTPS通信并不是通过公钥和私钥加密的,公钥和私钥只用在握手过程中,当客户端请求到真正的公钥后,会生成一个随机数(对称**)并用公钥加密,发送给服务器,后续的通信就用对称**加密了。这样做的原因是对称**加解密过程太耗时了。
结论:数字证书是为了保证公钥的真实,公钥的真实是为了保证对称**的安全。