A在向B进行通信时,如果是以明文的方式进行通信,中间窃听者会获得双方的传输的数据hello。
HTTPS要解决如下问题:
A发给B的hello消息包,即使被中间人拦截到了,也无法得知消息的内容
如何做到安全
这个问题,很多人马上就想到了各种加密算法,什么对称加密、非对称加密、DES、RSA、XX、。。。。
做到安全的最终目的:
A与B通信的内容,有且只有A和B有能力看到通信的真正内容
对于解决方案,很容易就想到了对消息进行加密。
A与B这样的简单通信模型,我们很容易做出选择:
这就是对称加密算法,其中图中的密钥S同时扮演加密和解密的角色。
只要这个密钥S不公开给第三者,同时密钥S足够安全,就可以解决通信的安全问题。
但是,在WWW环境下,我们的Web服务器的通信模型没有这么简单:
如果服务器端对所有的客户端通信都使用同样的对称加密算法,无异于没有加密。那怎么办呢?即能使用对称加密算法,又不公开密钥?
答案是:Web服务器与每个客户端使用不同的对称加密算法:
如何确定对称加密算法
首先需要解决服务器端怎么告诉客户端该使用哪种对称加密算法问题。
可以通过协商。
但是,你协商的过程是没有加密的,还是会被中间人拦截。那再对这个协商过程进行对称加密好了,但是对协商过程加密的加密还是没有加密,怎么办?再加密不就好了……进入了鸡生蛋蛋生鸡的问题了。
如何对协商过程进行加密
密码学领域中,有一种称为“非对称加密”的加密算法,特点是私钥加密后的密文,只要是公钥,都可以解密,但是公钥加密后的密文,只有私钥可以解密。私钥只有一个人有,而公钥可以发给所有的人。
虽然服务器端向A、B……的方向还是不安全的,但是至少A、B向服务器端方向是安全的。
解决了协商加密算法的问题:使用非对称加密算法进行对称加密算法协商过程。
到这里明白了为什么HTTPS同时需要对称加密算法和非对称加密算法。
协商什么加密算法
要达到Web服务器针对每个客户端使用不同的对称加密算法,同时,也不能让第三者知道这个对称加密算法是什么,该怎么解决?
使用随机数,就是使用随机数来生成对称加密算法。这样就可以做到服务器和客户端每次交互都是新的加密算法、只有在交互的那一该才确定加密算法。
到这里明白了为什么HTTPS协议握手阶段会有这么多的随机数。
如何得到公钥
仔细思考下,如果使用非对称加密算法,客户端A,B需要一开始就持有公钥,否则无法进行加密。
所以需要解决A,B客户端安全的获得公钥问题。
可以有以下方案:
方案1. 服务器端将公钥发送给每一个客户端
方案2. 服务器端将公钥放到一个远程服务器,客户端可以请求得到
选择方案1,因为方案2又多了一次请求,还要另外处理公钥的存放问题。
公钥被调包了怎么办
对于方案1如果服务器端发送公钥给客户端时,被中间人调包了,怎么办?
通过下图来理解:
显然,让每个客户端的每个浏览器默认保存所有网站的公钥是不现实的。
使用第三方机构的公钥
公钥被调包的问题出现,是因为我们的客户端无法分辨返回公钥的人到底是中间人,还是真的服务器。这其实就是密码学中提的身份验证问题。
使用数字证书来解决,不能直接将服务器的公钥传递给客户端,而是第三方机构使用它的私钥对我们的公钥进行加密后,再传给客户端。客户端再使用第三方机构的公钥进行解密。
假如下图是设计的第一版“数字证书”,证书中只有服务器交给第三方机构的公钥,而且这个公钥被第三方机构的私钥加密了:
如果能解密,就说明这个公钥没有被中间人调包。因为如果中间人使用自己的私钥加密后的东西传给客户端,客户端是无法使用第三方的公钥进行解密的。
话到此,我以为解决问题了。但是现实中HTTPS,还有一个数字签名的概念,我没法理解它的设计理由。
仔细思考,其实第三方机构不可能只给你一家公司制作证书,它也可能会给中间人这样有坏心思的公司发放证书。这样的,中间人就有机会对你的证书进行调包,客户端在这种情况下是无法分辨出是接收的是你的证书,还是中间人的。因为不论中间人,还是你的证书,都能使用第三方机构的公钥进行解密。像下面这样:
第三方机构向多家公司颁发证书的情况:
客户端能解密同一家第三机构颁发的所有证书:
最终导致其它持有同一家第三方机构证书的中间人可以进行调包:
这个问题需要使用数字签名技术。
数字签名
数字签名可以解决同一机构办法的不同证书被篡改的问题。
证书应该放到客户端,客户端拿到证书后应该可以分辨证书是否被篡改了,如何才能具有这个辨别能力?
举例:比如你是HR,你手上拿到候选人的学历证书,证书上写了持证人,颁发机构,颁发时间等等,同时证书上,还写有一个最重要的:证书编号!我们怎么鉴别这张证书是的真伪呢?只要拿着这个证书编号上相关机构去查,如果证书上的持证人与现实的这个候选人一致,同时证书编号也能对应上,那么就说明这个证书是真实的。
客户端也同样可以采用这种机制,如下图:
这个"第三方机构"如果是个远端服务,整个交互都会慢了。所以,这个第三方机构的验证功能只能放在客户端的本地。
客户端本地如何验证证书
证书本身就已经告诉客户端怎么验证证书的真伪。
也就是证书上写着如何根据证书的内容生成证书编号。客户端拿到证书后根据证书上的方法自己生成一个证书编号,如果生成的证书编号与证书上的证书编号相同,那么说明这个证书是真实的。
同时,为避免证书编号本身又被调包,所以使用第三方的私钥进行加密。
这地方有些抽象,通过下图帮助理解:
证书的制作如图所示。证书中的“编号生成方法MD5”就是告诉客户端:你使用MD5对证书的内容求值就可以得到一个证书编号。
当客户端拿到证书后,开始对证书中的内容进行验证,如果客户端计算出来的证书编号与证书中的证书编号相同,则验证通过:
但是第三方机构的公钥怎么跑到了客户端的机器中呢?世界上这么多机器。
其实呢,现实中,浏览器和操作系统都会维护一个权威的第三方机构列表(包括它们的公钥)。因为客户端接收到的证书中会写有颁发机构,客户端就根据这个颁发机构的值在本地找相应的公钥。
到这里上文提到的,证书就是HTTPS中数字证书,证书编号就是数字签名,而第三方机构就是指数字证书签发机构(CA)。
CA如何颁发数字证书给服务器端的
CA如何颁发给网站管理员,而管理员又如何将这个数字证书放到我们的服务器上。
CA的申请流程如下:
拿到证书后,我们就可以将证书配置到自己的服务器上了。
HTTPS交互流程
HTTPS相比HTTP多了多次的交互,这也是性能相比HTTP差的原因之一。
上面繁琐的流程都是为了让客户端与服务器端安全地协商出一个对称加密算法。这就是HTTPS中的SSL/TLS协议主要干的活。剩下的就是通信时双方使用这个对称加密算法进行加密解密。
以下是一张HTTPS协议的真实交互图:
![](https://i-blog.csdnimg.cn/blog_migrate/37ddbab86b1c3f985e73ae7584d21e71.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37ddbab86b1c3f985e73ae7584d21e71.gif)
总结
![](https://i-blog.csdnimg.cn/blog_migrate/37ddbab86b1c3f985e73ae7584d21e71.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37ddbab86b1c3f985e73ae7584d21e71.gif)
HTTPS要保证客户端与服务器端的通信安全,必须使用的对称加密算法,但是协商对称加密算法的过程,需要使用非对称加密算法来保证安全,然而直接使用非对称加密的过程本身也不安全,会有中间人篡改公钥的可能性,所以客户端与服务器不直接使用公钥,而是使用数字证书签发机构颁发的证书来保证非对称加密过程本身的安全。这样通过这些机制协商出一个对称加密算法,就此双方使用该算法进行加密解密。从而解决了客户端与服务器端之间的通信安全问题。