HTTPS = HTTP + TLS/SSL
HTTP协议采用明文传输信息,存在信息窃听、信息篡改和信息劫持的风险,而协议TLS/SSL具有身份验证、信息加密和完整性校验的功能,可以避免此类问题发生。
TLS全称Transport Layer Security(安全传输层协议), 前身是SSL,故现在用TLS/SSL统称。是介于TCP和HTTP之间的一层安全协议,不影响原有的TCP协议和HTTP协议,所以使用HTTPS基本上不需要对HTTP页面进行太多的改造。
套用在TCP/IP四层模型里的结构如下:
TLS/SSL原理
TLS/SSL的功能实现主要依赖于三类基本算法:散列函数(Hash)、对称加密和非对称加密。
其利用非对称加密实现身份认证和密钥协商,对称加密算法采用协商的密钥对数据加密,基于散列函数验证信息的完整性。
TLS/SSL = 非对称加密 + 对称加密 + 散列算法
非对称加密
加密和解密使用不同密钥的加密算法,也称为公私钥加密。密钥成对出现,一般称为公钥(publickey)和私钥(privatekey),公钥加密的信息只能私钥解开,私钥加密的信息只能公钥解开。即服务器持有私钥,客户端持有公钥,客户端要发送的信息经过公钥加密后传递给服务器,服务器用私钥解密得到明文信息。
特点:
- 可以实现1对多的通信;
- 保密性比较好,只有公钥需要被传递,故私钥被劫持的概率很低;
- 安全性高,保密性保证私钥安全,因此安全性仅依赖于算法本身;
- 计算复杂,加密速度慢。
在TLS/SSL中,非对称加密仅用于“身份认证”和“密钥协商”,不在后续正文数据传输中使用,这是安全性与性能之间的平衡取舍。
对称加密
加密和解密使用相同密钥的加密算法。即客户端与服务器所持有的密钥是相同的,客户端要发送的信息经过密钥加密后传递给服务器,服务器用相同密钥解密得到明文信息。
特点:
- 通信方式是1对1,为了足够安全,服务器和N个客户端通信,需要维持N个密码记录;
- 安全性不仅取决于加密算法本身,密钥管理的安全性更是重要;
- 计算量小、加密速度快、加密效率高;
- 缺少吊销和修改密钥的机制。
在TLS/SSL中,对称加密的密钥是通过非对称加密的“密钥协商”产生的,这样就最大限度的保证了密钥的安全。由于其效率高的特点,正文数据传输使用了该加密方式。
散列函数(Hash)
一种将任意长度的消息压缩到某一固定长度的消息摘要的函数,常用于防止信息篡改并验证数据的完整性。
特点:
- 单向不可逆;
- 对输入非常敏感,即一点输入的改变都会导致结果不同;
- 输出长度固定。
在信息传输过程中,散列函数不能单独实现信息防篡改,因为明文传输,中间人可以修改信息之后重新计算信息摘要,因此需要对传输的信息以及信息摘要进行加密。
在TLS/SSL中,“密钥协商”的最后步骤和传输正文信息都会带上散列函数计算出的信息摘要,他们一起经过对称加密后传输,用来验证完整性。
PKI体系
非对称加密的隐患
前面讲到“身份验证”和“密钥协商”是TLS/SSL的基础功能,要求的前提是合法的服务器掌握着对应的私钥。但非对称加密算法无法确保服务器身份的合法性,因为公钥并不包含服务器的信息。
假定出现以下的情况:
- 客户端C和服务器S进行通信,中间节点M截获了二者的通信;
- 节点M自己计算产生一对公钥pub_M和私钥pri_M;
- C向S请求公钥时,M把自己的公钥pub_M发给了C;
- C使用公钥pub_M加密的数据能够被M解密,因为M掌握对应的私钥pri_M,而C无法根据公钥信息判断服务器的身份,从而C和M之间建立了"可信"加密连接。
如图,中间节点M和服务器S之间再建立合法的连接,因此C和S之间通信被M完全掌握,M可以进行信息的窃听、篡改等操作,这类攻击被称为“中间人攻击”。
身份验证CA和证书
为了解决上述的隐患,关键是确保获取公钥途径是合法的,能够验证服务器的身份信息,为此需要引入权威的第三方机构CA。
CA全称Certificate Authority(证书颁发机构),它负责核实公钥的拥有者的信息,并颁发认证"证书",同时能够为使用者提供证书验证服务,即PKI体系。
证书 = 公钥 + 申请者与颁发者信息 + 有效时间 + 域名信息 + 签名
CA认证流程如下:
客户端会内置信任CA的证书信息(包含公钥),如果CA不被信任,则找不到对应CA的证书,证书也会被判定非法。
也可以这样理解,网站千千万,浏览器厂商没办法一家一家去认证,于是跟CA合作,通过维护一个CA列表,只要网站有经过这个列表里CA的认证,就可以信任该网站的证书。
TLS/SSL握手过程
TLS/SSL握手过程也就是所谓的HTTPS四次握手(不含证书验证步骤)。
1.客户端发起请求,以明文传输请求信息,包含版本信息,加密套件候选列表,压缩算法候选列表,随机数random_C(明文),扩展字段等信息。
2.服务端返回协商的信息结果,随机数random_S(明文),证书链等。
3.对证书进行验证,包括证书可信性、有效性等,可能需要联系CA。
4.细分为四步:
- client_key_exchange:客户端计算产生随机数字Pre-master,并用证书公钥加密,发送给服务器;
- 客户端根据random_C、random_S以及Pre-master,计算得到协商密钥enc_key(即对称加密用的密钥);
- change_cipher_spec:客户端通知服务器后续的通信都采用协商的通信密钥和加密算法进行加密通信;
- encrypted_handshake_message:结合之前所有通信参数的hash值与其它相关信息生成一段数据,采用协商密钥enc_key进行加密,然后发送给服务器用于数据与握手验证;
5.细分为四步:
- 服务器使用私钥解密Pre-master,根据random_C、random_S以及Pre-master,计算得到协商密钥enc_key;
- 计算之前所有接收信息的hash值,然后解密客户端发送的encrypted_handshake_message,验证数据和密钥正确性;
- change_cipher_spec:验证通过之后,服务器同样发送change_cipher_spec以告知客户端后续的通信都采用协商的密钥与算法进行加密通信;
- encrypted_handshake_message:服务器也结合所有当前的通信参数信息生成一段数据并采用协商密钥enc_key加密并发送到客户端;
6.握手结束,开始使用协商密钥enc_key进行对称加密通信(包含hash完整性验证)。
示意图如下:
HTTPS的使用成本
- 证书费用及维护更新
一般正规CA颁发的证书都是需要付费购买的,并且到期后还得续费。
- 增加了访问延迟
分析前面的握手过程,一次完整的握手至少需要两端依次来回两次通信,至少增加延时2RTT,利用会话缓存从而复用连接,延时也至少1RTT。
- 消耗较多CPU资源
加解密是需要消耗性能的,前面也有提到非对称加密的特点,因此会成为性能瓶颈。
HTTPS的优化
TLS False Start
在TLS/SSL协商第二阶段,也就是浏览器生成最后一个随机数并用公钥加密发送给服务器后,立即发送加密的应用层数据,而无需等待服务器的确认。
Session Identifier(会话标识符)
如果用户的一个业务请求包含了多条的加密流,客户端与服务器要反复握手,必定导致更多的时间损耗。或某些特殊情况导致会话中断,需要重新握手。
服务器为每一次的会话生成并记录一个sessionId,发送给客户端,客户端重新连接只需要提供这个id,不需要重新握手。
OCSP Stapling
OCSP全称Online Certificate Status Protocol。由web服务器向OCSP server周期性地查询证书状态,获得一个带有时间戳和签名的OCSP response并缓存它。当有客户端发起请求时,web服务器会把这个response在TLS握手过程中发给客户端。
(谷歌浏览器默认只使用内置列表检查,故这个优化对谷歌无效)
HSTS(HTTP Strict-Transport-Security)
一个报文头部字段,告诉浏览器,接下来的一段时间内,当前域名(及其子域名)的后续通信应该强制性使用HTTPS,直到超过有效期为止。
形如:
- Strict-Transport-Security: max-age=31536000;includeSubDomains