HTTPS
1. 铺垫概念
加密:就是把明文进行一系列的变化,生成密文。
解密:就是把密文再进行一系列的变化,还原成明文。
密钥:密钥是加密和解密过程中使用的关键参数或密码。
为什么要进行加密?
运营商劫持事件。
保护数据隐私。
常见的加密方式:
对称加密
同一个密钥可以同时用作信息的加密和解密,特征是加密和解密所用的密钥是相同的。
特点:算法公开、计算量⼩、加密速度快、加密效率⾼。
非对称加密
需要两个密钥来进行加密和解密,这两个密钥是公开密钥(public key,简称公钥)和私有密钥(private key,简称私钥)。
特点:算法强度复杂、安全性依赖于算法与密钥,但是由于其算法复杂,而使得加密解密速度没有对称加密解密的速度快。
非对称加密最大的缺点就是运算速度非常慢。
通过公钥对明文加密,变成密文。
通过私钥对密文解密,变成明文。
也可以反着用
通过私钥对明文加密,变成密文。
通过公钥对密文解密,变成明文。
数据摘要 && 数据指纹
数字指纹(数据摘要),其基本原理是利用单向散列函数(Hash函数)对信息进行运算,生成一串固定长度的数字摘要。数字指纹并不是一种加密机制,但可以用来判断数据有没有被篡改。
数据摘要常见算法:MD5、SHA1、SHA256等算法,把无限的映射为有限,因此可能会有碰撞(两个不同的信息,算出的摘要相同,但是概率非常低)。
特征:和加密算法的区别是,数据摘要严格意义不是加密,因为没有解密的过程,通常用来进行数据的对比。
数字签名
- 数据摘要经过加密,得到数字签名。
2. HTTPS工作探究
HTTPS(Hypertext Transfer Protocol Secure)是在 HTTP 基础上通过 SSL/TLS协议提供加密、身份认证和数据完整性保护的安全通信协议。
先 TCP 三次握手,后 HTTPS 握手,协商出安全的通信。
方案1:只使用对称加密
如果通信双方都各自持有同一个密钥X,且没有别人知道,这两方的通信安全当然是可以被保证的(除非密钥被破解)。
但是浏览器无法预存全世界所有网站的对称密钥,所以需要首次连接时安全协商并验证对方身份。
假设 client 端密钥为 X,server 端如何得知 X?只使用对称加密,首次的时候,无法同步双方的对称密钥。因为是明文发送,会直接被中间人获取密钥 X。因此密钥的传输也必须要加密传输。这就形成一个无限套娃的问题了。
方案2:只使用非对称加密
首先服务端拥有一个公钥P和私钥P‘,客户端发送请求,服务器先把公钥P以明文的方式传输给客户端,之后客户端向服务器传输数据都通过该公钥加密后传送,从客户端到服务器这条通道似乎是安全的,因为只有服务器有对应的私钥P‘才能接开该公钥加密过的数据。
但是如果服务器通过私钥加密传输给客户端,那么浏览器可以用公钥进行解密,但是首次这个公钥是明文发送给客户端的,若该公钥被中间人劫持,那么就可以通过公钥来解密服务器向客户端发送的信息。无法保证服务器到客户端这条通过的安全性。
方案3:双方都使用非对称加密
服务端拥有公钥S与对应的私钥S’,客户端拥有公钥C与对应的私钥C’。
客户端和服务端交换公钥。
客户端给服务端发信息:先用服务端公钥S对数据加密,再发送,只能由服务器解密,因为只有服务器拥有对应的私钥S‘。
服务端给客户端发信息:先用客户端公钥C对数据加密,再发送,只能由客户端解密,因为只有客户端拥有对应的私钥C‘。
但依旧有安全问题,并且效率太低。而且如果客户端是浏览器的话,事实上也做不到,要面对数十亿个未知网站,不可能为每个网站预置密钥对。
方案4:非对称加密 + 对称加密
服务端具有非对称公钥S和私钥S‘。
客户端发起https请求,获取服务端公钥S。
客户端在本地生成对称密钥C,通过公钥S加密,发送给服务器。
服务器通过私钥S’解密,还原出客户端发送的对称密钥C,后续双方的通信都采用该对称加密的公钥进行通信。
以上方案2、方案3、方案4都存在一个共同的问题,如果最开始,中间人就开始攻击了呢?
服务器具有非对称加密算法的公钥S,私钥S‘。
中间人具有非对称加密算法的公钥M,私钥M‘。
客户端向服务器发起请求,服务器明文传送公钥S给客户端。
中间人劫持数据报文,提取公钥S并保存好,然后将被劫持的报文中的公钥S替换成为自己的公钥M,并将该报文发送给客户端。
客户端收到报文,提取公钥M(并不知道公钥已经被替换过了),然后客户端形成对称密钥X,用公钥M加密X,形成报文发送给服务器。
中间人劫持后,直接用自己的私钥M‘进行解密,得到对称密钥X,再用曾经保存的服务端公钥S进行重新加密,将报文推送给服务器。
服务器收到报文,用自己的私钥S’进行解密,得到通信密钥X。
此后,双方开始采用X进行对称加密,进行通信。但一切都在中间人掌握之中,劫持数据、窃听、修改都是可以的。
问题的本质是:客户端无法确定收到的公钥是否是目标服务器发送的,有没有被修改过。
3. HTTPS最终方案
3.1 引入证书
CA认证:服务端在使用HTTPS前,需要向CA机构申领一份数字证书,数字证书里含有证书申请者信息、公钥、域名信息等。服务器把证书传输给浏览器,浏览器从证书里获取公钥就行了,证书就如身份证,证明服务端公钥的权威性。
证书可以理解为一个结构化的字符串,包含了以下的信息:
证书发布机构。
证书有效时间。
域名。
服务端公钥。
数据摘要的Hash算法函数。
证书所有者。
数字签名(CA用私钥签发)。
…
3.2 理解数据签名和验证
数字签名的过程:
CA机构拥有自己的非对称加密的私钥A和公钥A’。
CA机构对服务端申请的信息进行hash,形成数据摘要(其基本原理是利用单向散列函数对信息进行运算,生成一串固定长度的字符串)。
然后对数据摘要使用CA机构自己的私钥A‘加密,得到数字签名S。
服务端申请的证书明文和数字签名S 共同组成了数字证书,交给服务端。
总结:
服务器生成自己的公钥和私钥,将公钥及相关身份信息(域名、组织等)提交给CA机构。CA验证信息无误后,会生成一个包含这些明文信息以及其数字签名的证书——该数字签名正是CA对您的明文信息进行数据摘要后,用CA机构自己的私钥加密生成的认证标识,并将数据签名拼接到明文信息后。
证书的验证:
客户端收到证书后,将明文信息和数字签名分离。
将该明文数据采用同样的hash函数,生成对应的数据摘要。
数字签名使用CA机构的公钥A进行解密,得到对应的数据摘要。
若两者的数据摘要一致,则此证书代表有效。
怎么采用同样的hash函数?
- 证书的明文信息中会明确标注使用的是什么Hash函数。
CA机构的公钥怎么来的?
- 浏览器和操作系统会内置CA机构的公钥,以及CA认证的子机构的公钥。
为什么这个过程能保证安全?
任何对明文信息的篡改都会导致哈希值发生变化。
攻击者无法伪造签名,因为只认CA的私钥。
若攻击者也注册一个合格的CA证书呢?
- 中间人攻击面临的根本困境是:证书与域名严格绑定。当用户访问bank.com时,必须获得bank.com域名的证书才能建立连接。即使中间人持有attacker.com等其他域名的合法证书,当它拦截请求并试图用自己的证书响应时,浏览器会立即发现证书中声明的域名(attacker.com)与用户实际访问的域名(bank.com)不符,从而触发安全警告并阻断连接。这种强制性的域名验证机制,使得中间人无法用其他证书冒充目标网站。
3.3 HTTPS 的流程(对称加密 + 非对称加密 + 证书认证)
服务器具有非对称加密算法的公钥S,私钥S‘。
中间人具有非对称加密算法的公钥M,私钥M‘。
客户端向服务器发起请求,服务器发送证书,而不是裸公钥。
中间人试图劫持,但发现:
无法直接修改明文公钥S,因为篡改后,客户端对数字签名解密后的数字摘要与明文哈希后的数字摘要匹配不上。
无法提取公钥S,因为被CA签名保护,而数据摘要的哈希函数是单向散列,只能从数据生成摘要,无法从摘要反推原始数据,这是它的核心设计。
如果用自己申请的合法的证书,证书中的域名与客户端实际访问服务器的域名不一致,也能识别出来。
客户端收到服务器证书,验证证书是否合法。
将该明文数据采用同样的hash函数,生成对应的数据摘要;数字签名使用CA机构的公钥A进行解密,得到对应的数据摘要。若两者的数据摘要一致,则此证书代表有效。
检查证书的有效期。
检查证书中域名是否匹配。
中间人无法修改,因此安全通信建立。
客户端生成对称密钥X,通过服务器公钥S加密,将加密后的对称密钥发送给服务器。
此后,双方开始采用对称密钥X进行通信。