HTTPS
本文主要介绍HTTPS的原理及握手过程。
用途
HTTPS作为HTTP协议的替代协议,主要提升了通信过程的安全,避免了一些中间人攻击,包括中间人窃取数据包,篡改数据包,中间人冒充通信双方等。
针对以上三种攻击方式,协议需要对数据包进行加密,即使中间人窃取到了数据包也无法理解;另外需要对数据包校验,确保没有被篡改;最后还需要对通信双方进行身份认证。
加解密
HTTPS协议采用非对称加密结合对称加密的方式对数据包进行加解密。
为什么这么做呢?由于非对称加密的算法耗时过长,对服务器和客户端资源占用比较严重,所以在建立会话时才会用非对称算法对会话密钥(session key)进行加密,建立会话后的通信过程,使用这个会话密钥作为对称加密的密钥,对数据包进行对称加密。
关于非对称加密:使用对方的公钥(公开的)对明文加密,对方接收到密文后使用自己的私钥(私有的)进行解密。通信双方会先获取对方的公钥,这个公钥通常从CA获取(后面会提及)。
完整性校验
即使我们对数据包加密了,但是在传输过程中如果有中间人对数据包进行了篡改,接收方收到的消息也不是原来的消息,所以需要对数据包进行校验。
我们知道Hash函数能将长消息映射为短消息,且是单向的,无法用短消息还原成长消息(暂时的),不同的长消息几乎不会输出相同的短消息(抗碰撞性强)。所以我们可以让发送方对明文进行Hash运算得到Hash值,附在明文后面,然后对明文+Hash值加密;这样即使中间人篡改了密文,接收方拿到密文解密,再对解密后的消息做Hash,与真正的Hash值做对比,如果不一致就说明被篡改了。
身份认证
要对通信双方进行认证,需要一个大家都认可的第三方CA(证书颁发机构Certificate Authority),申请者可以向CA申请证书,CA会制作数字证书,只要得到这个证书,就代表通信方经过了认证。
CA用自己的私钥对申请者的公钥+一些额外信息(CA做的数字签名)进行加密,得到证书;接收证书的一方用CA公钥(默认信任CA,所以接收方已经得到了CA的公钥)对证书进行解密,如果能顺利解密(包括对完整性进行校验),就证明证书没有被篡改,并且得到了对方的公钥,同时也认证了发送方确实是真正的发送方而不是中间人。
这种方式也可以用来防止抵赖,让对方把消息做一个数字签名,和现实中签名的作用是一样的;如果用对方的公钥能解开校验这个签名,说明这个消息必然是对方发送的。
HTTPS握手过程
客户端请求
客户端发出加密通信的请求,称为ClientHello请求,主要提供以下信息:
- 支持的协议版本,比如TLS 1.0;
- 一个客户端生成的随机数,用于生成会话密钥;
- 支持的加密算法,比如RSA等;
- 支持的压缩方法,GZIP等;
服务器响应
服务器收到请求后,发出响应,称为ServerHello,包含以下内容:
- 确认使用的加密通信协议版本,如果客户端与服务器支持的版本不一致,服务器将关闭加密通信;
- 一个服务器生成的随机数,用于生成会话密钥;
- 确认使用的加密算法;
- 服务器证书;
如果服务器需要确认客户端的身份,会要求客户端提供客户端的证书,例子:金融机构往往只允许认证客户连入自己的网络,就会向正式客户提供USB密钥,里面就包含了一张客户端证书。
客户端回应
客户端收到服务器的回应后,首先会验证服务器的证书;如果证书不可信,会警告访问者是否要继续通信;如果证书没问题,客户端会从证书中取出服务器的公钥,然后继续发送一下信息:
- 一个随机数,用服务器的公钥加密,防止被窃取;
- 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。
- 客户端握手结束通知,表示客户端的握手阶段结束,这项也是前面发送的所有内容的Hash值,提供给服务器用于校验。
这一步由客户端和服务器总共生成了3个随机数,大大加强了随机数的随机性,保证了后续会话密钥的随机性。
如果上一步服务器要求提供客户端证书,客户端会发送证书等相关信息。
服务器最后的回应
服务器收到第三个随机数后,计算生成本次会话用的会话密钥,然后发送一下信息:
- 编码改变通知,表示随后的信息都用商定的加密方法和密钥发送;
- 服务器握手结束通知,表示握手阶段结束,同样包含前面发送的所有内容的Hash值,提供给客户端进行校验。
握手阶段结束,接下来服务器和客户端会进行加密的通信,使用会话密钥对内容进行加密。
主要参考https://developers.weixin.qq.com/community/develop/article/doc/000046a5fdc7802a15f7508b556413