本文是对「一文读懂HTTPS加密机制」的提炼。
HTTPS等价为HTTP+SSL。由于http协议是明文传输的,因此很容易被截获,所以是不安全的,需要采用加密机制。
为何不能只用对称加密
对称加密是加密和解密都用同一个密钥,服务器给浏览器发消息,首先用自身的密钥加密。但如果想要浏览器解密报文,必须把这个密钥也发送给浏览器,这样密钥很容易被截获,所以是不安全的。
为何不能只用非对称加密
非对称加密是指服务器有一个私钥和一个公钥,私钥始终自己保存,公钥发送给浏览器。如果用私钥加密,则用公钥解密;如果用公钥加密,则用私钥解密。
服务器向浏览器发送消息的加密过程如下:首先服务器用私钥进行加密,发送公钥给浏览器,然后浏览器利用得到的公钥解密。这样如果服务器和浏览器都有各自的一对公钥和私钥,那就可以达到预期了。然而HTTPS并没有这样做,因为相比于对称加密,非对称加密的成本非常高,两组非对称加密会带来很大的延迟。
用对称+非对称加密存在什么问题
由于两组非对称加密时延很长,有一种做法是服务器发给浏览器用非对称机密,反过来用对称加密。也就是说流程如下:服务器发送给浏览器的数据,先用服务器自身的私钥加密,与公钥一起传给浏览器,浏览器随机生成密钥,将该密钥用服务器传递过来的公钥加密,这样浏览器传给服务器的数据就可以用服务器自身的私钥进行解密,保证了安全。HTTPS协议也是基于这种机密模式设计的。
但是这样存在一个问题,即中间人攻击。就是当服务器传递数据和公钥给浏览器时,可能会被拦截。假设被一台中间机器拦截,可以通过公钥进行解密,同时将公钥篡改为自己的公钥,发送给浏览器。这样当浏览器发回其密钥时,就可以截获浏览器的密钥。因此存在这种中间人攻击的风险。
数字签名
现在的问题就是:浏览器该如何才能知道,发过来的公钥正是未经过篡改的服务器的公钥?这里就用到了数字证书。一个网站在使用HTTPS协议前需要向CA机构申领一份数字证书,数字证书里含有证书持有者信息、公钥信息等。服务器把证书传输给浏览器,浏览器从证书里获取公钥就可以了。那么如何利用数字证书来保证真实性呢?
这里就用到了数字签名技术:
签名过程如下:CA证书也拥有公钥和私钥,首先用CA证书里的散列函数对数据进行hash,然后用CA证书的私钥对hash后的散列值加密,得到数字签名S。数据和数字签名一起,组成了数字证书发送给浏览器。随后浏览器要验证这个证书的真实性。
验证过程如下:首先将数字证书拆分成签名S和明文T,用CA机构的公钥对签名S进行解密(浏览器对CA机构是信任的,因此会预安装CA机构的根证书,因此可以拿到可信的CA机构公钥)。随后用证书里指明的hash算法对明文T进行hash得到T‘,如果T‘与签名S相等,那么表明证书可信。
通过这种方式,服务器传递公钥给浏览器,浏览器传递密钥给服务器,就成为了一个相对安全的过程。hash在这里更多起到一个提升效率的作用,将长度较长的明文,转化为例如128长度的哈希值,会提高加解密效率。
试想下会不会存在中间人攻击?(1)如果中间人篡改数据,那么他没有CA机构的私钥,无法用私钥加密,浏览器用公钥解密会失败,因此会发现篡改;(2)如果中间人将证书调包,那么证书里显示的域名等信息与浏览器请求的不一致,也会发现受到了攻击。因此不会存在中间人攻击的现象。