一、加密基础
1、单向加密
也称为不可逆加密,对明文产生一个密文,并且不能通过密文解出对应的明文
使用场景:一般用于信息摘要,密钥加密等
常见的单向加密算法有:
- MD5
- SHA:SHA192,SHA256
特点:
- 不可逆
- 输入一样,输出相同
2、对称加密
对称加密,用一个密钥,对明文进行加密,同理,同这把密钥,也可以对密文进行解密。也就是说加密和解密,可以用同一个密钥,这种加密方法就是对称加密
常见的对称加密算法有:
- DES
- 3DES
- AES
特点:
- 加密方和解密方使用同一个密钥
- 加密解密速度比较快
3、非对称加密
使用公钥和私钥进行加密解密,可以使用私钥加密,公钥进行解密,同理也可以使用公钥加密,私钥进行解密
常见的非对称加密算法有:
- RSA
- DSA
特点:
- 使用两把密钥进行加密和解密,即公钥和私钥
- 公钥加密私钥解密,私钥加密公钥可以解密
- 加密或者解密,速度非常慢
- 私钥和公钥是成对出现的
二、HTTPS加密原理
1、为什么需要加密
HTTP的内容是明文传输的,数据传输的过程会经过中间代理服务器、路由器、WiFi热点、通信服务运营商等多个物理节点,如果信息在传输过程中被劫持,那么传输的内容就完全暴露了,甚至劫持者还可以篡改信息而不被通信双方察觉,这就是中间人攻击。
所以我们需要对传输的内容进行加密。
2、加密流程演变
1)对称加密
首先可以想到的就是对称加密,对称加密速度较快,通信过程中对信息进行加密解密的开销不大,只要通信双方约定好一个密钥,之后每次传输的时候都采用这个密钥进行加密解密即可。
但是这其中存在一个问题,就是双方如何约定一个仅双方知晓的密钥。如果服务器生成后传输给浏览器,那么这个密钥仍有被劫持的可能,那么后续的加密显然就失效了。所以我们将对称加密用于数据传输,但需要一种安全的方式保证对称加密的密钥传输。
2)非对称加密
非对称加密采用公钥和私钥两把密钥,服务端将公钥发送给客户端,之后客户端每次传输数据之前都先采用公钥对要传输的数据进行加密,这样就保证了客户端到服务器端信息的安全,因为只有持有私钥的服务端才可以解密出客户端所发送的数据。
但是服务器端发送的数据却是无法保证的,因为公钥是公开的,那么其他人就可以截获并解密出服务端发给客户端的数据。
一组公钥私钥可以解决单向的安全,那么其实用两组公钥私钥也可以保证传输的安全,但是非对称加密的效率低
- 某网站服务器拥有公钥A与对应的私钥A’;浏览器拥有公钥B与对应的私钥B’。
- 浏览器把公钥B明文传输给服务器。
- 服务器把公钥A明文给传输浏览器。
- 之后浏览器向服务器传输的内容都用公钥A加密,服务器收到后用私钥A’解密。由于只有服务器拥有私钥A’,所以能保证这条数据的安全。
- 同理,服务器向浏览器传输的内容都用公钥B加密,浏览器收到后用私钥B’解密。同上也可以保证这条数据的安全。
3)非对称加密+对称加密
既然非对称加密可以保证客户端发给服务端的信息只有服务端能读取,那么我们不难想到让客户端生成对称传输的密钥,然后用非对称加密中服务端发布的公钥对该密钥进行加密发给服务端,服务端收到之后用非对称加密中的私钥解密即可拿到对称加密的公钥。之后双方就可以采用这个密钥进行对称加密传输了。这样不仅保证了安全,效率也够高(相比于用两组公钥私钥进行数据的传输)
3、存在问题
上面的方式看似安全,但其实还是存在一定的问题的。
服务端在发送公钥A给客户端时,如果被截取,那么攻击者可以把服务端本要发送给客户端的公钥A替换成自己生成的公钥B,这个操作对于客户端来说是不可得知的。那么后续客户端生成密钥X再加密发出时其实使用的就是攻击者生成的公钥B去进行加密的,那么攻击者就可以通过自己的私钥B’解密出客户端生成的对称加密密钥X,然后再用服务端的公钥A加密后返回给服务端。
那么后续双方通信的内容同样还是被攻击人所窃取了。
4、解决方式
其实之所以会存在这样的问题主要是因为服务端无法保证自己发出的公钥能够不被篡改地发送给客户端,即客户端不能确定接收到的公钥一定是服务端发送的。
如果按照之前的方式再次对公钥进行加密,那么加密的密钥的传输仍然还是重复上面的问题。所以在这里引入了第三方机构(CA机构)来解决这样的情况。
1)数字证书
网站在使用HTTPS前,需要向CA机构申领一份数字证书,数字证书里含有证书持有者信息、公钥信息等。服务器把证书传输给浏览器,浏览器从证书里获取公钥就行了。
证书就如身份证,证明”该公钥对应该网站“
当然这里还得保证证书本身的真实性,即防止证书本身在传输过程中被篡改。
数字证书组成部分:
- 服务端生成的公钥
- 颁发者(证书认证机构)
- 证书有效期
- 生成摘要的算法
- 指纹(摘要)
- 签名算法
- 序列号:证书的唯一标识
2)生成方式
数字签名的制作过程:
- CA机构拥有非对称加密的私钥和公钥。
- CA机构对证书明文数据T进行hash。
- 对hash后的值用私钥加密,得到数字签名S。
- 明文和数字签名共同组成了数字证书。
为什么需要对证书先进行哈希之后再加密:
因为非对称加密效率很差,而证书中包含的信息一般又比较长,所以先对证书进行哈希得到一个固定长度的值之后再进行加密可以有效降低耗时。
浏览器验证过程:
- 拿到证书得到明文T和数字签名S。
- 用CA机构的公钥对S解密(由于是浏览器信任的机构,所以浏览器保有它的公钥),得到S’。
- 用证书里指明的hash算法对明文T进行hash得到T’。
- 显然通过以上步骤,T’应当等于S‘,除非明文或签名被篡改。所以此时比较S’是否等于T’,等于则表明证书可信。
这里的核心其实就是在于浏览器保存有了CA机构的公钥,所以避免了这个公钥的传输导致的被篡改的可能。
其实这里的证书是操作系统和浏览器本身就会预装一些他们信任的根证书,如果其中有CA机构的根证书,就可以拿到它对应的可信公钥了。如果浏览器没有给这个网站颁发证书的机构的根证书,那么你就得手动下载安装该机构的根证书(风险自己承担)。安装后,你就有了它的公钥,就可以用它验证服务器发来的证书是否可信了。
因为签名是用CA机构的私钥加密得到的,攻击者即使篡改了数据,由于没有私钥也更改不了数字签名,那么最后验证时则会发现S‘和T’不相同的情况,说明证书不可信,从而终止向服务器传输信息,防止信息泄露给中间人。
并且证书中还保存了网站的域名和信息等,如果攻击者用自己在CA机构申请的证书进行替换,则浏览器接收到证书时就会发现与当前访问的网站不同,从而也避免了证书被掉包的情况。
5、整体流程
- 网站提交相关信息申请证书
- CA机构向证书中写入摘要算法、域名、网站公钥等信息,并通过摘要算法对证书进行哈希,之后用自己的私钥对摘要进行加密计算出签名
- 将证书颁发给申请者,申请者将证书放到服务器
- 浏览器访问网站,服务器将证书发送给浏览器
- 浏览器根据自身保存或操作系统内置的CA证书拿到CA的公钥,通过其对签名进行解密得到摘要
- 通过整数中的摘要算法对证书进行哈希,比较结果是否等于上一步得到的摘要
- 如果不相等则证明证书被篡改,如果相等则通过证书验证,浏览器拿到服务端的公钥
- 浏览器生成密钥并使用拿到的服务端公钥进行加密传输给服务端
- 服务端使用私钥计算出密钥并将其存储在服务端内部(通过sessionID标识对应的浏览器)
- 后续浏览器每次请求都携带sessionID,服务器会根据sessionID找到对应的密钥进行加密解密操作