1.什么是HTTP协议?
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议),位于TCP/IP模型当中的应用层。HTTP协议通过请求/响应的方式,在客户端和服务端之间进行通信。HTTP协议的信息传输完全以明文的方式,不做任何加密,相当于在网络上“裸奔”,所以容易遭受中间人的恶意截获甚至篡改(中间人攻击)。

2.什么是HTTPS协议?
HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。
3.对称加密和非对称加密
对称加密
对称加密采用了对称密码编码技术,它的特点是文件加密和解密都是使用相同的密钥。
这种方法在密码学中叫做对称加密算法,对称加密算法使用起来简单快捷,密钥较短,且破译困难,除了数据加密标准(DES),另一个对称密钥加密系统是国际数据加密算法(IDEA),它比DES的加密性好,而且对计算机功能要求也没有那么高。
非对称加密
与对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey)。
公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。
因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。
4.HTTPS流程
1.服务端首先把自己的公钥(Key1)发给证书颁发机构,向证书颁发机构申请证书。

2.证书颁发机构自己也有一对公钥私钥。机构利用自己的私钥来加密Key1,并且通过服务端网址等信息生成一个证书签名,证书签名同样经过机构的私钥加密。证书制作完成后,机构把证书发送给了服务端。

3.当客户端向服务端请求通信的时候,服务端不再直接返回自己的公钥(Key1),而是把自己申请的证书返回给客户端。
4.客户端收到证书以后,要做的第一件事情是验证证书的真伪。需要说明的是,各大浏览器和操作系统已经维护了所有权威证书机构的名称和公钥。所以客户端只需要知道是哪个机构颁布的证书,就可以从本地找到对应的机构公钥,解密出证书签名。
客户端对证书验证成功后,就可以放心地再次利用机构公钥,解密出服务端的公钥Key1。
客户端本地如何验证证书呢?
证书本身就已经告诉客户端怎么验证证书的真伪,也就是证书上写着如何根据证书上的方法自己生成一个证书编号,如果生成的证书编号与证书上的证书编号相同,那么证明这个证书是真实的。同时,为避免证书编号本身又被调包,所以使用第三方机构的私钥进行加密。
证书就是HTTPS中的数字证书,证书编号就是数字签名,而第三方机构就是指数字证书签发机构(CA)

5.客户端生成自己的对称加密密钥Key2,并且用服务端公钥Key1加密Key2,发送给服务端。

6.服务端用自己的私钥解开加密,得到对称加密密钥Key2。于是客户端与服务端开始用Key2进行对称加密的通信。

延伸:
为什么数据传输不能直接用非对称加密呢?
既然对称加密走不通,那我们能不能用非对称加密来解决呢,比如RSA。我们知道,非对称加密会有一对秘钥,即公钥和私钥。通常私钥只保存在服务器端,公钥可以发送给所有的客户端,公钥加密的内容,只有私钥可以解开,私钥加密的内容,所有的公钥都可以解开。

这种方式同样存在在传输公钥的过程中被中间人获取的风险,但相比对称加密分配不同秘钥给客户端的方式,非对称加密至少可以保证中间人是无法破解客户端通过公钥加密的内容,因为私钥只保存在服务器端,只有私钥可以破解公钥加密的内容。
既然中间人截取到公钥之后,拿到公钥也没有用,那中间人能否在拦截到服务端返回的信息之后,将这个真的公钥替换掉,传一个假的公钥给用户呢?答案是肯定的。
如下图所示,MITM即中间人(Man-in-the-MiddleAttack)可以拦截到服务端的真公钥,然后自己生成一对假的公钥和私钥,将假公钥传给客户端,客户端加密数据之后发送到服务端,中间又被中间人拦截,中间人用自己的私钥解密之后,即获取到了客户端发送的数据,然后中间人可以篡改请求的数据,使用真公钥进行加密,传回服务端。

为什么需要 CA 认证机构颁发证书?
虽然非对称加密更接近解决数据加密传输的问题,但依然存在公钥被掉包之后,数据被篡改的风险。那我们能否在客户端做一个校验,保证浏览器接收到的公钥是合法的?这种思路是对的,但如果是我们自己来完成浏览器的这套验证,我们又如何把校验的信息传到浏览器上呢?不进行校验信息的加密传输,在传输过程中依然有泄漏的风险。如果进行加密,也存在以上同样的加密问题了。
于是业界专门成立了一个颁发证书的认证机构,通常服务提供者需要向认证机构申请证书,认证机构通过申请者公钥、申请者的组织信息和个人信息、签发机构 CA 的信息、有效时间、证书序列号等信息的明文,使用散列函数计算公开的明文信息的信息摘要,然后,采用 CA 的私钥对信息摘要进行加密,生成的密文即是签名。同时,认证架构将会在操作系统或浏览器中内置CA的ROOT证书。浏览器安装后会内置一些权威第三方认证机构的公钥,比如VeriSign、Symantec以及GlobalSign等等。

当浏览器接收到服务端的数据时,首先会用散列函数计算公开的明文信息的信息摘要,然后采用浏览器内置的公钥对签名进行解密,解密出来的信息摘要与散列函数进行对比,如果一致则说明数据没有被篡改。

为什么要有签名?
以上CA颁发证书时,会提供一个数字签名,那我们为什么需要这样一个数据签名呢?直接将服务端的公钥发送给第三方机构,使用私钥加密不就可以了吗?但是我们要知道,谁都可以去第三方机构申请证书的,而第三方机构都是使用的一对私钥和公钥。假设我们的中间人也去申请了,这个时候中间人可以截取到服务端的返回证书,然后更换为自己的,之后再发给客户端。而由于第三方也是合法的申请证书的人,所以客户端解密成功,利用中间人的公钥进行加密,之后发送到服务端时,中间人截取之后,利用自己的私钥解密获取到信息。

而通过数字签名,由于使用了域名等信息,只要浏览器发现不是当前域的,则认为是被篡改的,如果是当前域,解密之后发现签名不一样,也同样认为是被篡改的。
