本文将重点介绍关于 HTTPS 的几个实战指南。
原文地址:服务端指南 | HTTPS 项目实战指南
博客地址:blog.720ui.com/
本文将重点介绍关于 HTTPS 的几个实战指南。
- HTTPS 使用剖析
- HTTPS 项目场景
- HTTPS 设计上的借鉴
- HTTPS 降级攻击
HTTPS 使用剖析与项目场景
HTTP 协议没有加密机制,可以通过 SSL 或 TLS 加密 HTTP 的通信内容。因此,HTTPS 是 HTTP 的安全版,在 HTTP 协议中加入 SSL 层,它由两部分组成:HTTP 与 SSL。其中,SSL 是独立于 HTTP 的协议,它不仅可以适用于 HTTP 协议,还可以配合 WebSocket 等协议一起使用。
为什么使用 HTTPS
HTTP 协议没有加密机制,通信内容是明文传输的,没有经过任何安全处理。然而,互联网的任何角落都可能存在通信内容在传输过程中被中间者窃听、篡改、冒充等风险。其中,任何角落指的是用户的通信内容在浏览器和服务器中间传输必须要经过的节点,比如 WIFI 热点,路由器,防火墙,反向代理,缓存服务器等。因此,HTTP 协议通信存在的威胁不言而喻,中间者可以窃听隐私,使用户的敏感信息泄露;篡改网页,例如中间者向页面插入广告内容,甚至有的中间者进行流量劫持,例如有的时候会发现域名没有输错,结果却跳转到了一个钓鱼网站,因为这个网站被中间者劫持了。
因此,为了解决窃听、篡改、冒充等风险,HTTPS 的价值就体现出来了,HTTPS 可以进行通信内容加密,使第三方无法窃听。HTTPS 可以进行身份认证,一旦通信内容被篡改,通信双方会立刻发现。此外,HTTPS 可以保证通信内容的完整性,防止通信内容冒充或者篡改。
SSL 与 TLS
HTTP 协议可以通过 SSL 或 TLS 加密 HTTP 的通信内容。其中,SSL 最初由网景通信公司率先倡导与开发,最新版本是 SSL 3.0。目前,由 IETF 主导与管理。IETF 以 SSL 3.0 为基准,在 SSL 3.0 协议规范之上又制定了 TLS 1.0、 TLS 1.1 和 TLS 1.2。
HTTPS 原理剖析
为了更好地理解 HTTPS,先来观察一下 HTTPS 的通信步骤。
第一步,用户在浏览器里输入一个支持 HTTPS 协议的网址,例如 blog.720ui.com,此时会发起一个 HTTPS 请求,通过 TCP 和服务器建立连接,其中使用 443 端口。
第二步,服务器向客户端发送证书,其中包括域名,申请证书的公司,证书的公钥等信息。
第三步,客户端通过 SSL 或 TLS 对证书进行解析,验证公钥是否有效,例如验证颁发机构与验证过期时间等信息,如果发现证书异常,则会弹出一个警告框,提示证书存在问题。如果证书没有问题,那么就生成一个密钥,然后向服务器发送证书公钥加密后的密钥。
第四步,服务器用证书私钥进行解密,获得客户端传过来的密钥。
第五步,服务器用客户端的密钥加密后的信息发送给客户端。
第六步,客户端用密钥解密服务端传过来的信息,验证服务端传过来的信息是否可以用密钥进行解密。
第七步,客户端用密钥加密请求内容,然后将通信内容发送给服务端。
第六步,服务端用密钥解密请求内容,并进行业务处理后用密钥加密响应内容,然后将通信内容发送给客户端。
在以上流程中,HTTPS 协议将对称加密算法与非对称加密算法的优势相结合。使用对称加密算法对通信内容进行快速加密,从而弥补了非对称加密算法处理速度慢的问题,并保证通信内容的机密性。同时,使用非对称加密算法将对称加密算法的密钥进行加密,保证对称加密算法的密钥的安全交换。因此,HTTPS 协议先通过非对称加密算法进行密钥的安全交换,并在建立通信连接后,使用对称加密算法进行通信,保证通信内容的机密性。
HTTPS 项目场景
真实的业务场景是比较复杂的。这里,整理 3 个项目中遇到的比较复杂的应用场景。
对 HTTPS 协议的通信内容进行 CDN 加速
对 HTTPS 协议的通信内容进行 CDN 加速主要两个方案。
方案一,服务器(源站)提供证书给 CDN 厂商,包括证书公钥和证书私钥,CDN 负责内容缓存,CDN 有缓存则直接响应,以 HTTP 或 HTTPS 的形式回源。这个方案,适用仅对防劫持、防篡改有需求,而愿意提供证书给 CDN 的源站加速。
方案二,服务器(源站)不提供证书给 CDN 厂商,因此 CDN 需要存放证书公钥,服务器(源站)存放证书私钥。在 CDN 与浏览器进行 TLS 的认证和密钥协商过程中,通过安全的信道把协商过程中的信息以 HTTP 或 HTTPS 的形式转发给源网站。这个方案,CDN 不做缓存,仅以自有的加速网络,将用户的请求快速送到服务器(源站),降低公网延迟。因此,这个方案适用于对安全要求更高,不愿将证书私钥共享给 CDN 的源站加速。
对 HTTPS 的域名通过 CNAME 绑定到另外一个 HTTPS 域名上
对 HTTPS 的域名通过 CNAME 绑定到另外一个 HTTPS 域名上,这个情况下,需要两个证书,因为每个证书跟自己的域名进行绑定,即使它们都在同一个服务器上,也不能使用同一个证书。
两台服务器的证书问题
因为安全问题,CA 证书部署在一台服务器上面,但是业务系统部署在另外一台服务器上面,这种情况就比较难办。此时,需要借助 Nginx 进行反向代理,回源到具体的服务器。
HTTPS 设计上的借鉴
对称加密算法可以将敏感的信息在通信过程中通过 DES 或 AES 进行加密传输,然后在客户端和服务端直接进行解密。但是,将密钥编码在代码中存在安全隐患,因为密钥可能会泄漏。因此,更安全的做法是将密钥保存在数据库中,由服务端的接口下发密钥,在使用时由客户端获取密钥并加载进内存,并且通过非对称加密算法保证密钥在通信过程中的安全交换。实际上,这个通信流程可以借鉴 HTTPS 协议的流程,将对称加密算法与非对称加密算法的优势相结合。其中,使用对称加密算法对通信内容进行快速加密,从而弥补了非对称加密算法处理速度慢的问题,并保证通信内容的机密性。同时,使用非对称加密算法将对称加密算法的密钥进行加密,保证对称加密算法的密钥的安全交换。
这里,介绍一个文件加密与解密的真实案例。需求场景是为了防止平台资源被第三方抓取,因此需要对平台的资源进行加密,并且只能用于平台的客户端使用。为了更好地理解整个通信流程,先来观察一下加密的通信步骤。
第一步,客户端 SDK 使用 RSA 加密算法,生成一对公私钥,或者称之为加密密钥与解密密钥。
第二步,客户端 SDK 向服务端请求 AES 密钥,因为密钥保存在服务器的数据库中,由服务端的接口下发密钥。其中,请求参数包括资源 ID 与 RSA 加密算法的公钥。
第三步,服务端使用客户端 SDK请求参数中的资源 ID,生成一个 AES 密钥,并保存到数据库中。
第四步,服务端使用客户端 SDK请求参数中的 RSA 加密算法的公钥,加密AES 密钥。
第五步,服务器发送给客户端 SDK加密后的 AES 密钥。
第六步,客户端 SDK 使用RSA 加密算法的私钥解密,获取到真正的 AES 密钥。
第七步,客户端 SDK 使用真正的 AES 密钥对资源文件进行加密。
理解了资源文件的加密的通信流程,再来观察一下解密的通信步骤。
与资源文件的加密的通信流程类似,客户端 SDK 使用 RSA 加密算法,生成一对公私钥,客户端 SDK 向服务端请求 AES 密钥,服务端使用客户端 SDK请求参数中的资源 ID 查询 AES 密钥,服务端使用客户端 SDK请求参数中的 RSA 加密算法的公钥,加密AES 密钥,并且服务器发送给客户端 SDK加密后的 AES 密钥,客户端 SDK 使用RSA 加密算法的私钥解密,获取到真正的 AES 密钥,最后,客户端 SDK 使用真正的 AES 密钥对资源文件进行解密。
HTTPS 降级攻击的场景剖析与解决之道
HTTPS 一定安全么
HTTP 协议没有加密机制,通信内容是明文传输的,没有经过任何安全处理。因此,为了解决窃听、篡改、冒充等风险,采用 HTTPS 协议。HTTPS 可以进行通信内容加密,使第三方无法窃听。HTTPS 可以进行身份认证,一旦通信内容被篡改,通信双方会立刻发现。此外,HTTPS 可以保证通信内容的完整性,防止通信内容冒充或者篡改。那么,使用了 HTTPS 就能确保通信内容的安全传输吗?理论上,是这样的,但是事实上,现实却不是如此,因为设计与实现 SSL/TLS 协议出现了漏洞,导致攻击者同样可以攻击一些旧版本的 SSL/TLS 协议。这其中就包括 SSL 3.0。
什么是 HTTPS 降级攻击
因为浏览器的兼容性问题,当浏览器进行 HTTPS 连接失败的时候,将会尝试使用旧的协议版本,于是加密协议由更加安全的协议,比如 TLS 1.2 降级成 SSL 3.0。因此,在 HTTPS 降级攻击中,攻击者利用旧版本的 SSL/TLS 协议的漏洞,其中包括 SSL 3.0 的漏洞,然后攻击者获取安全连接当中某些可以降级成 SSL 3.0 的加密后的明文的通信内容进行攻击。
注意的是,如果服务器支持 SSL 3.0 协议,同时,攻击者又能作为中间人控制浏览器发起漏洞版本的 HTTPS 请求,此时,虽然攻击者窃听到加密的通信内容,但加密的协议存在漏洞,可以进行降级攻击,解密这些加密的通信内容可以获取有价值的信息,例如用户的隐私数据。
HTTPS 降级攻击的解决之道
目前,解决 HTTPS 降级攻击的唯一方法是禁用 SSL 3.0 协议,并防止 TLS 1.2 协议、 TLS 1.1 协议与 TLS 1.0 协议降级到 SSL 3.0 协议。其中,禁用 SSL 3.0 协议的策略有很多,这里主要介绍下 Nginx 如何防止 TLS 1.2 协议、 TLS 1.1 协议与 TLS 1.0 协议降级到 SSL 3.0 协议以下版本,从而防止 HTTPS 降级攻击。
Nginx 原先的配置,如下所示。此时,如果 Nginx 原先的配置没有额外的配置,那么在 Nginx 中隐性默认是 SSLv3 TLSv1 TLSv1.1 TLSv1.2。
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;复制代码
Nginx 禁用 SSL 3.0 协议,并防止 TLS 1.2 协议、 TLS 1.1 协议与 TLS 1.0 协议降级到 SSL 3.0 协议的配置非常简单,只需要屏蔽 SSLv3 参数即可,如下所示。
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;复制代码
总结下,HTTPS 能确保通信内容的安全传输吗?答案是不一定,因为设计与实现 SSL/TLS 协议出现了漏洞,导致攻击者同样可以攻击一些旧版本的 SSL/TLS 协议,其中就包括 SSL 3.0,可能会被攻击者进行 HTTPS 的降级攻击。因此,SSL 3.0 协议并不安全,为了防止 HTTPS 的降级攻击,需要禁用 SSL 3.0 协议,确保TLS 1.2 协议、 TLS 1.1 协议与 TLS 1.0 协议降级到 SSL 3.0 协议以下版本。
(完)
更多精彩文章,尽在「服务端思维」微信公众号!