HTTP 安全方面的缺点
容易被窃听
HTTP 本身不具备加密的功能, 也就是说 HTTP 报文使用明文(指未经过加密的报文)方式发送。
原理
在基础篇(传送门)讲到 TCP/IP 协议族的工作机制,数据会经过多次转发才到达目的地,因此只需要收集在互联网上流动的数据包(帧),进行拼接和分析,就能进行窃听。并不是说只有明文才会被窥视,密文也会,但密文即使被窥视,在不知道解密方法的情况下也是不清楚内容的。
解决的办法
- 通信的加密:通过增加一个加密层来实现,相对于形成一个安全的隧道,隧道内再进行 HTTP 通信,是一种免改造 HTTP 本身的做法,但会增加通信消耗。
- 内容的加密:服务器和客户端约定一种对通信内容的加密协议,每次发送加密、接收解密,但在 Web 上并不合适,因为 js 是动态脚本语言,分析客户端代码就能知道加解密方法。
不验证通信方的身份
HTTP 协议中的请求和响应不会对通信方进行确认,因此很容易进行伪装。
原理
对客户端来说,一般依赖 DNS 寻找目标服务器,但如果 DNS 被污染,也无法确认请求是否发送给了预期的服务器;对服务器来说,基础篇(传送门)讲到 HTTP 的“无状态”的特性,会导致服务器“照单全收”,无法确认接收响应的客户端是否合法、是否是无意义的DoS攻击。
解决的办法
一般通过引入证书机制解决。证书由值得信任的第三方机构颁发,用以证明服务器确实是该域名合法的服务器,证书也作为建立加密隧道的凭证,只有合法的客户端才能正确解密响应信息。
无法证明报文完整性
所谓完整性是指信息的准确度。若无法证明其完整性,通常也就意味着内容很容易被篡改。
原理
HTTP 协议本身并没关于完整性验证的约定,原理与前面讲到的“容易被窃听”相同,也就是说如果在某次转发的过程中修改了数据,服务器和客户端都是不可知的。最常见的就是上游 ISP(互联网服务提供商)或路由器往网页上添加广告。
解决的办法
通过加密处理及摘要功能可以很好的解决,加密在前面已经讲过,这里不再重复;所谓摘要,就是发送方使用 MD5 或 SHA-1 等对数据敏感(数据改动会导致计算结果不同)的算法生成散列值,在信息中附带它,接收方采用相同算法如果能得到相同结果,就能证明数据没有被篡改过。
HTTPS 基础知识
为了解决上述中的 HTTP 在安全方面的缺点,于是诞生了 HTTPS。
HTTPS 全称 Secure HyperText Transfer Protocol(安全超文本传输协议)或 HTTP over SSL ,是一个安全通信通道,用于在客户计算机和服务器之间交换信息。它使用安全套接字层进行信息交换,简单来说它是 HTTP 的安全版,是使用 TLS/SSL 加密的 HTTP 协议。
HTTPS = HTTP + TLS/SSL
TLS 全称 Transport Layer Security(安全传输层协议), 前身是 SSL,故现在用 TLS/SSL 统称。是介于 TCP 和 HTTP 之间的一层安全协议,不影响原有的 TCP 协议和 HTTP 协议,所以使用 HTTPS 基本上不需要对 HTTP 页面进行太多的改造。
套用在TCP/IP四层模型里的结构如下:
TLS/SSL 原理
TLS/SSL 是独立于 HTTP 的协议,所以不光是 HTTP 协议,其他运行在应用层的 SMTP 和 Telnet 等协议均可配合 TLS/SSL 协议使用。可以说 TLS/SSL 是当今世界上应用最为广泛的网络安全技术。
TLS/SSL 的功能实现主要依赖于三类基本算法:散列函数 Hash、对称加密和非对称加密,其利用非对称加密实现身份认证和密钥协商,对称加密算法采用协商的密钥对数据加密,基于散列函数验证信息的完整性。
TLS/SSL = 非对称加密 + 对称加密 + 散列算法
非对称加密
加密和解密使用不同密钥的加密算法,也称为公私钥加密。密钥成对出现,一般称为公钥(publickey)和私钥(privatekey),公钥加密的信息只能私钥解开,私钥加密的信息只能公钥解开。即服务器持有私钥,客户端持有公钥,客户端要发送的信息经过公钥加密后传递给服务器,服务器用私钥解密得到明文信息。
特点:
- 可以实现 1 对多的通信;
- 保密性比较好,只有公钥需要被传递,故私钥被劫持的概率很低;
- 安全性高,保密性保证私钥安全,因此安全性仅依赖于算法本身;
- 计算复杂,加密速度慢。
在 TLS/SSL 中,非对称加密仅用于“身份认证”和“密钥协商”,不在后续正文数据传输中使用,这是安全性与性能之间的平衡取舍。
对称加密
加密和解密使用相同密钥的加密算法。即客户端与服务器所持有的密钥是相同的,客户端要发送的信息经过密钥加密后传递给服务器,服务器用相同密钥解密得到明文信息。
特点:
- 通信方式是 1 对 1,为了足够安全,服务器和 N 个客户端通信,需要维持 N 个密码记录;
- 安全性不仅取决于加密算法本身,密钥管理的安全性更是重要;
- 计算量小、加密速度快、加密效率高;
- 缺少吊销和修改密钥的机制。
在 TLS/SSL 中,对称加密的密钥是通过非对称加密的“密钥协商”产生的,这样就最大限度的保证了密钥的安全。由于其效率高的特点,正文数据传输使用了该加密方式。
散列函数(Hash)
一种将任意长度的消息压缩到某一固定长度的消息摘要的函数,常用于防止信息篡改并验证数据的完整性。
特点:
- 单向不可逆;
- 对输入非常敏感,即一点输入的改变都会导致结果不同;
- 输出长度固定。
在信息传输过程中,散列函数不能单独实现信息防篡改。因为明文传输,中间人可以修改信息之后重新计算信息摘要,因此需要对传输的信息以及信息摘要进行加密。
在 TLS/SSL 中,“密钥协商”的最后步骤和传输正文信息都会附加一种叫做 MAC(Message Authentication Code)的报文摘要 ,由散列函数生成,用来验证完整性。
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(证书颁发机构),它负责核实公钥的拥有者的信息,并颁发认证"证书",同时能够为使用者提供证书验证和吊销服务。
CA 提供的整套服务也叫 PKI 体系, 全称 Public Key Infrastructure,即公钥基础设施。
证书 = 公钥 + 申请者与颁发者信息 + 有效时间 + 域名信息 + 签名
CA 认证流程如下:
客户端会内置信任 CA 的证书信息(包含公钥),如果 CA 不被信任,则找不到对应 CA 的证书,证书也会被判定非法。
也可以这样理解,网站千千万,浏览器厂商没办法一家一家去认证,于是跟 CA 合作,通过维护一个 CA 列表,只要网站有经过这个列表里 CA 的认证,就可以信任该网站的证书。
注意
- 申请证书不需要提供私钥,确保私钥永远只能服务器掌握;
- 证书的合法性仍然依赖于非对称加密算法,证书主要是增加了服务器信息以及签名;
- 服务器最终拿到的证书一般是经过多次派生后的证书,也就是说在服务器证书和根证书之间可能存在多个中间证书,这种证书链的设计有利于减少私钥泄露的风险并且方便吊销。(见图)
- 只要中间证书有相同的公钥和私钥,服务器证书就能同时可以被多条证书链验证。
相关概念
- 根证书:颁发者和使用者相同,自己为自己签名,也叫自签名证书,一般为 CA 持有;
- 中间证书:根证书可以签发给二级机构,二级机构可以继续签发给三级机构,以此类推,这些介于根证书与服务器证书直接的证书称为中间证书。
- 证书链:服务器证书、中间证书与根证书在一起组合成的自下而上的信任传递链,就是一条合法的证书链。
- 证书吊销的方法:CRL(Certificate Revocation List)即证书吊销列表;OCSP(Online Certificate Status Protocol)即证书状态在线查询协议。
TLS/SSL 握手过程
TLS/SSL握手过程也就是所谓的HTTPS四次握手(不含证书验证步骤)。
- 客户端发起请求,以明文传输请求信息,包含版本信息,加密套件候选列表,压缩算法候选列表,随机数 random_C(明文),扩展字段等信息。
- 服务端返回协商的信息结果,随机数 random_S(明文),证书链等。
- 对证书进行验证,包括证书可信性、有效性等,可能需要联系 CA。
细分为四步:
- client_key_exchange:客户端计算产生随机数字 Pre-master,并用证书公钥加密,发送给服务器;
- 客户端根据 random_C、random_S 以及 Pre-master,计算得到协商密钥 enc_key(即对称加密用的密钥);
- change_cipher_spec:客户端通知服务器后续的通信都采用协商的通信密钥和加密算法进行加密通信;
- encrypted_handshake_message:结合之前所有通信参数的 hash 值与其它相关信息生成一段数据,采用协商密钥 enc_key 进行加密,然后发送给服务器用于数据与握手验证;
细分为四步:
- 服务器使用私钥解密 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 加密并发送到客户端;
- 握手结束,开始使用协商密钥 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/SSL 握手过程中发给客户端。
(谷歌浏览器默认只使用内置列表检查,故这个优化对谷歌无效)
HSTS(HTTP Strict-Transport-Security)
一个报文头部字段,告诉浏览器,接下来的一段时间内,当前域名(及其子域名)的后续通信应该强制性使用 HTTPS,直到超过有效期为止。
形如:
Strict-Transport-Security: max-age=31536000;includeSubDomains
加解密计算分离
由于最消耗服务器性能的部分是加解密,为了减少业务服务器的负担,可以将这部分工作分配给一个专门优化的高计算性能的服务器,并配备有硬件加速功能的硬件,以达到最佳性能。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。