1、缘起
我们从一个聊天软件说起,我们要实现A能发一个hello消息给B。如果我们要实现这个聊天软件,只考虑安全性问题,要做到:
A发送B的hello消息包,即使被中间人拦截到了,也无法得知消息的内容。
2、使用对称加密算法加密A与B的通信内容
所以我们对通信安全性的理解就是说A与B通信的内容,有且只有A和B有能力看到通信的真正内容。
那么,我们很容易想到,对A和B的通信内容进行加密。这边选用对称加密算法,只要密钥不公开给第三者,同时密钥足够安全。那么世界上就会有且只有A与B知道如何加密和解密他们之间的消息。
3、每个客户端有唯一的对称加密算法
但是一台服务器会对应多个客户端,如果都使用同样的对称加密算法,那就无异于没有加密。那怎么办呢?怎么能做到既能使用对称加密算法,又不公开密钥?
答案是:Web服务器与每个客户端使用不同的对称加密算法。
4、对协商过程进行加密
慢着,另一个问题来了,我们的服务器怎么告诉客户端该使用哪种对称加密算法呢?当然是通过协商。但是协商的过程如果没有加密的话,被中间人拦截的话岂不是拿到算法了。 那我们再对这个协商过程进行对称加密就好了,那你对协商过程加密的加密还是没有加密,怎么办?再加密不就好了……好吧,进行鸡生蛋蛋生鸡的问题了。
5、采用非对称加密算法对协商过程进行加密
那么对于4中鸡生蛋蛋生鸡的问题如何解决呢? 如何对协商过程进行加密?密码学领域中,有一种称为“非对称加密”的加密算法,特点是私钥加密后的密文,只要是公钥,都可以解密;但是公钥加密后的密文,只有私钥可以解密。私钥只有一个人有,而公钥可以发给所有的人。
这样私钥保存在服务端,公钥广播给每个客户端。虽然服务端向A、B…的方向还是不安全的,但是至少A、B等客户端向服务端方向是安全的。
至此,如何协商加密算法的问题,我们解决了: 使用非对称加密算法进行对称加密算法协商过程。
6、使用随机数生成对称加密算法
要达到web服务器针对每个客户端都使用不同的对称加密算法并且不被第三者猜出来这个对称加密算法,怎么办?使用随机数,就是使用随机数来生成对称加密算法。这样就可以做到服务端和客户端每次交互都是新的加密算法,而且只有在交互的那一刻才确定加密算法。(你这些明白为什么HTTPS协议握手阶段会有那么多随机数了吧)
7、如何得到公钥?
细心的人可能已经注意到了如果使用非对称加密算法,我们的客户端A、B需要一开始就持有公钥,处理方式就是服务端一开始就将公钥发给每一个客户端。
8、公钥被调包了怎么办?
如果一个中间人将客户端A的公钥调包,给了A一个假的公钥,再拿真的公钥伪装成A和服务器通信。怎么办
9、使用第三方机构的公钥
公钥被调包的问题出现,是因为我们的客户端无法分辨返回公钥的人到底是中间人,还是真的服务器。这其实就是密码学中提的身份验证问题。
我们想应该这样解决这个问题: 既然服务器需要将公钥传给客户端,这个过程本身是不安全,那么我们为什么不对这个过程本身再加密一次?可是,你是使用对称加密,还是非对称加密?这下好了,我感觉又进了鸡生蛋蛋生鸡问题了。
问题的难点是如果我们选择直接将公钥传递给客户端的方案,我们始终无法解决公钥传递被中间人调包的问题。
所以想了个办法,我们不能直接将服务器的公钥传递给客户端,而是第三方机构使用它的私钥对我们的公钥进行加密后,再传给客户端。客户端再使用第三方机构的公钥进行解密。
10、证书被掉包?
但是第三方机构发的证书也有可能被中间人进行调包。客户端在这种情况下是无法分辨接收到的证书是中间人的还是第三方机构的。
11、客户端本地怎么验证证书呢?
怎么解决10的问题呢?那就需要客户端有能力辨别证书是否被篡改。而且不能有远端协助验证,所以只能放在客户端本地进行验证证书。
客户端本地怎么验证证书呢?答案是证书本身就已经告诉客户端怎么验证证书的真伪。
也就是证书上写着如何根据证书的内容生成证书编号。客户端拿到证书后根据证书上的方法自己生成一个证书编号,如果生成的证书编号与证书上的证书编号相同,那么说明这个证书是真实的。
同时,为避免证书编号本身又被调包,所以使用第三方的私钥进行加密。
但是第三方机构的公钥怎么跑到了客户端的机器中呢?世界上这么多机器。
其实呢,现实中,浏览器和操作系统都会维护一个权威的第三方机构列表(包括它们的公钥)。因为客户端接收到的证书中会写有颁发机构,客户端就根据这个颁发机构的值在本地找相应的公钥。
题外话:如果浏览器和操作系统这道防线被破了,就没办法。想想当年自己装过的非常规XP系统,都害怕。
说到这里,想必大家已经知道上文所说的,证书就是HTTPS中数字证书,证书编号就是数字签名,而第三方机构就是指数字证书签发机构(CA)。
12、CA如何颁发数字证书给服务端?
这个问题应该问:CA如何颁发给我们的网站管理员,而我们的管理员又如何将这个数字证书放到我们的服务器上。
就是网站管理员去CA机构申请,申请拿到证书后,我们就可以将证书配置到自己的服务器上了。
13、整理下思路
我们通过推算的方式尝试还原HTTPS的设计过程。这样,我们也就明白了为什么HTTPS比HTTP多那么多次的交互,为什么HTTPS的性能会差,以及找到HTTPS的性能优化点。
而上面一大堆工作都是为了让客户端与服务器端安全地协商出一个对称加密算法。这就是HTTPS中的SSL/TLS协议主要干的活。剩下的就是通信时双方使用这个对称加密算法进行加密解密。
14、一句话总结HTTPS
HTTPS要使客户端与服务器端的通信过程得到安全保证,必须使用的对称加密算法,但是协商对称加密算法的过程,需要使用非对称加密算法来保证安全,然而直接使用非对称加密的过程本身也不安全,会有中间人篡改公钥的可能性,所以客户端与服务器不直接使用公钥,而是使用数字证书签发机构颁发的证书来保证非对称加密过程本身的安全。这样通过这些机制协商出一个对称加密算法,就此双方使用该算法进行加密解密。从而解决了客户端与服务器端之间的通信安全问题。
15、HTTPS通信过程
16、总结
一开始服务端就向客户端传过去证书(公钥),客户端本地校验证证书(根据证书内容生成编号然后和证书上的签名比较是否一样)无误后,客户端生成一个随机值(对称加密算法密钥),然后用证书对随机值进行加密(只有服务端的私钥才能解密),服务端解密拿到随机值也就是对称加密算法,开始正常通信。