为什么要用https
HTTP 由于是超文本传输协议,是一个简单的请求-响应协议,它通常运行在TCP之上,它是明文传输,不能保证数据的完整性,不能保证是否被窃听,不能保证数据是否被篡改
https采用了一些加解密,数字证书,数字签名的技术保证了通信的安全,一般我们认为安全的通信需要包括以下四个原则::机密性、完整性,身份认证和不可否认。
- 机密性:即对数据加密,解决了窃听风险,因为即使被中间人窃听,由于数据是加密的,他也拿不到明文;
- 完整性:指数据在传输过程中没有被篡改,如果修改,接收方也能识别出来,从来判定接收报文不合法;
- 身份认证:确认对方的真实身份,这样就解决了冒充风险,用户不用担心访问的是某宝结果却在和钓鱼网站通信的问题;
- 不可否认: 即不可否认已发生的行为,比如小明向小红借了 1000 元,但没打借条,或者打了借条但没有签名,就会造成小红的资金损失。
HTTPS 通信原理简述
首先要了解有哪些加密算法,都有哪些特点
- 对称加密算法
加解密都用的同一个秘钥,用同一个秘钥加密,同一个秘钥解密
加解密速度快
适合加密大量数据
常用的对称加密算法有 AES、DES、3DES、RC4、SM4 等。 - 非对称加密算法
有一对秘钥,公钥和私钥,公钥加密私钥解密,私钥加密公钥解密
(注:私钥加密其实这个说法其实并不严谨,准确的说私钥加密应该叫私钥签名。因为私密加密的信息公钥是可以解密的,而公钥是公开的,任何人都可以拿到,用公钥解密叫做验签。)
加密算法复杂,加密速度慢
比较安全
常用的非对称加密算法有RSA、DSA、SM2 - 哈希算法,也叫散列算法,也叫摘要算法
不可逆,只能加密,无法解密
哈希函数输出长度必须是固定的,并且与输入长度无关
一般用来验证数据的完整性
常用的哈希算法有SM3,、md5、SHA1、SHA256
实现对称加密,需要三项,确定对称加密算法,生成对称秘钥(一个随机数,一般一次一秘,每一次的通信都会重新生成),明文
实现非对称加密,也需要三项,确定非对称加密算法,公钥(一般一个网站有一组公私钥对),明文
实现哈希算法,需要两项,确定哈希算法,明文,生成固定长度密文
对称加密报文
既然 HTTP 是明文传输的,那我们给报文加密不就行了,对称加密有具有加解密速度快,性能高的特点,也是 HTTPS 最终采用的加密形式。 所以使用对称加密的方式来给报文进行加解密。
但是这里有一个关键问题:对称加密的通信双方要使用同一把密钥,这个密钥是如何协商出来的?如果通过报文的方式直接传输密钥,之后的通信其实还是在裸奔,因为这个密钥会被中间人截获甚至替换掉,这样中间人就可以用截获的密钥解密报文,甚至替换掉密钥以达到篡改报文的目的。
非对称加密结合对称加密算法
这个时候就用到了非对称算法,解决单向对称密钥的传输问题 公钥加密只能私钥解密,而私钥只有服务器有,不在中间传输。用非对称算法的公钥加密对称秘钥,用对称秘钥加密报文,服务器端先用私钥解密出对称秘钥,再解密出报文,这样就实现了加密传输的安全。
但是问题又来了, server 怎么把公钥安全地传输给 client 呢。如果直接传公钥,也会存在被中间人调包的风险。这个时候就用到了数字证书,解决公钥传输信任问题
数字证书
服务器得去公证人这里先登记,把服务器的公钥、网站域名等等信息报上去,公证人拿到这些信息后,计算一个 Hash 值,然后再用公证人的 私钥 把Hash值进行加密,加密后的结果就是 数字签名。最后,公证人把登记的信息和这个数字签名合在一起,封装了一个新的文件发给服务器,登记就完成了,而这个新的文件就是数字证书。
服务器拿到证书后,可要好生保管,因为通信的时候,服务器须要将他们的证书发给我们浏览器验证。我们浏览器拿到证书后,把证书里面的信息也计算一遍Hash,再用提前记录好的 公证人的公钥 把证书里的数字签名进行解密,得到公证人计算的Hash,两个一对比,就知道这证书是不是公证人签发的,以及有没有被篡改过了!只有验证成功才能继续后面的流程,要不然就是冒充的!
由于只有 CA 的公钥才能解密签名,如果客户端收到一个假的证书,使用 CA 的公钥是无法解密的,如果客户端收到了真的证书,但证书上的内容被篡改了,摘要比对不成功的话,客户端也会认定此证书非法。如果中间人也向CA申请了证书,劫持客户端的请求,返回自己的证书,也是行不通的,因为客户端会验证网站域名等信息,这一下总算解决了中间人冒充的问题。
抓包
charles 这些中间人为啥能抓到明文的包呢?其实就是用了证书调包这一手法,想想看,在用 charles 抓 HTTPS 的包之前我们先要做什么,当然是安装 charles 的证书。
这个证书里有 charles 的公钥,这样的话 charles 就可以将 server 传给 client 的证书调包成自己的证书,client 拿到后就可以用你安装的 charles 证书来验签等,验证通过之后就会用 charles 证书中的公钥来加密对称密钥了。整个流程如下:
由此可知,charles 这些中间人能抓取 HTTPS 包的前提是信任它们的 CA 证书,然后就可以通过替换证书的方式进行瞒天过海,所以我们千万不要随便信任第三方的证书,避免安全风险。
证书链
我们可以向 CA 申请证书,但全世界的顶级 CA(Root CA) 就那么几个,每天都有很多人要向它申请证书,它也忙不过来。这个时候用到了证书链,它会授权下一级,下下级 ,这样我们就只要找一级/二级/三级 CA 申请证书即可。怎么证明这些证书被 Root CA 授权过了呢,小一点的 CA 可以让大一点的 CA 来签名认证。比如一级 CA 让 Root CA 来签名认证,二级 CA 让一级 CA 来签名认证,Root CA 没有人给他签名认证,只能自己证明自己了,这个证书就叫「自签名证书」或者「根证书」,我们必须信任它,不然证书信任链是走不下去的(这个根证书其实是内置在操作系统中的,在浏览器中可以看到根证书和中间证书和SSL证书,及证书链)
现在我们看看如果站点申请的是二级 CA 颁发的证书,client 收到之后会如何验证这个证书呢,实际上 service 传了传给二级 CA 的证书外,还会把证书信任链也一起传给客户端,这样客户端会按如下步骤进行验证:
- 浏览器就使用信任的根证书(根公钥)解析证书链的根证书得到一级证书的公钥+摘要验签;
- 拿一级证书的公钥解密一级证书,拿到二级证书的公钥和摘要验签;
- 再然后拿二级证书的公钥解密 server 传过来的二级证书,得到服务器的公钥和摘要验签,验证过程就结束了。
HTTPS 通信过程
发起请求、验证身份、协商秘钥、加密会话
一、 客户端向服务端发起ssl请求
- 告诉服务器自己支持哪些加密算法
- 客户端生成随机数R1发送给服务端
二、 服务端向客户端发送数字证书(ssl证书)
- 服务端生成随机数R2
- 选择一种双方都支持的加密算法
- 服务端把证书、公钥、随机数R2、会话密钥生成算法,一同发给客户端
三、 客户端验证数字证书
- 验证数字证书的有效性,首先验证数字证书上的CA证书的根证书是否存在,再使用CA根证书的公钥解密证书签名数据,得到CA机构计算的摘要。然后通过证书里提供的摘要算法对数据(证书中的相关的明文信息)采用相同的散列函数(Hash算法)计算得到信息摘要,然后通过自己生成的摘要与CA机构的摘要比对。如果一致,则可以确认证书的合法性,即公钥合法
- 验证证书合法性,包括证书是否吊销、是否到期、域名是否匹配,通过后则进行后面的流程
- 获得证书的公钥、会话密钥生成算法、随机数R2
- 生成一个随机数R3(预主密钥)。
- 根据会话密钥算法使用R1、R2,和预主密钥R3生成会话密钥;
- 用服务端证书的公钥加密随机数R3并发送给服务端。
四、 服务器得到会话密钥
- 服务器用私钥解密客户端发过来的随机数R3
- 根据会话秘钥算法使用R1、R2,和预主密钥R3生成会话密钥;
五、 客户端与服务端开始进行加密会话
- 客户端发送加密数据给服务端
- 服务端响应客户端( 解密接收数据:服务端用会话密钥解密客户端发送的数据; 加密响应数据:用会话密钥把响应的数据加密发送给客户端。)
- 客户端用会话密钥解密服务端响应的数据
六、 客户端与服务端开始进行加密会话