About HTTPS!

EVENT

2010 年 5 月,谷歌开始提供 HTTPS 加密搜索服务。

2014 年 8 月,谷歌曾调整搜索引擎算法,并称「比起同等 HTTP 网站,采用 HTTPS 加密的网站在搜索结果中的排名将会更高」。

2014 年 9 月, 百度在一份公告中表示「百度不会主动抓取 HTTPS 网页」

2015 年 3 月, 百度启用全站 HTTPS 加密搜索服务

2016 年 9 月,微信宣布小程序要求使用 HTTPS 请求进行网络通信。

2016 年 9 月,百度曾就「HTTPS 站点如何建设才能对百度友好」问题发布了一篇文章,给出了「提高 HTTPS 站点的百度友好度」的四项建议及具体操作。

2016 年 10 月,苹果要求 iOS 设备发起的所有请求必须在 2017 年 1 月 1 号之前使用 HTTPS。(WebView 内的请求不在要求范围内)

众所周知,HTTPS 在效率上要比 HTTP 差、在部分搜索引擎上 HTTPS 也会对SEO也会造成一定的负面影响、站点要支持 HTTPS 也必然会付出不少的精力。

可既然有这么多的问题和成本在里面,那为什么这么多的大厂还在争先恐后的推动 HTTPS 的发展和建设呢?

HTTP vs HTTPS

WHAT

HTTP (Hypertext Transfer Protocol)

HTTP 是在七层网络模型中的应用层的协议。

由客户端发送请求 Request 和 服务器端响应 Response 构成,是一个标准的 Client & Server 模型。

HTTP 协议运行在 TCP 协议之上,所有传输的内容都是明文。

HTTP 是一个无状态的协议。

「无状态」,稍稍解释一下。自己在刚接触「无状态」的时候,一直很懵逼。
书上说,无状态是指把每个请求都作为与之前任何请求都无关的独立的事务。
通俗一点,就是说当你第二次访问服务器的时候,服务器并不知道你是谁。

可事实是,基于我们平时的使用习惯, 我们清楚的知道,服务器在你每次请求的时候,其实都知道你是谁。
这是因为浏览器和服务器之间已经基于 HTTP 无状态的特性,做了很多默认约定工作,用来保证请求的连续性。让本来无状态的 HTTP 协议,变得更加方便使用。

目前,为了保持客户端在服务器端的访问状态,被采用最多的实现方式就是 Cookie 了。与 Cookie 相对的一个解决方案是 Session,它是通过服务器来保持状态的。

这也就解释了,为什么我们在 Chrome 登录之后,在 Safari 依然需要重新登录。
因为不同浏览器之间的 Cookie,在默认情况下并不是共享的。
客户端的 Cookie 不同,客户端在服务器端的访问状态,服务器端自然也就无法识别了。

SSL (Secure Socket Layer)

HTTPS (Hypertext Transfer Protocol Secure)

HTTPS 运行在 SSL/TLS 之上,SSL/TLS 运行在 TCP 之上,所有传输的内容都经过加密的。

HTTPS = HTTP + SSL/TLS

明文

你想要给女神阿花写信。

你把想说的话,写在信封里,因为一些原因,你不方便直接把信给阿花,只能把信封交给了女神家隔壁的老王,老王负责把你的信交给阿花。

这就是 HTTP 方式的信息传输。老王可以拆开查看信件内容,也可以直接修改里面的内容。

阿花给你的回复,也要先经过老王,老王依然可以拆开查看,然后修改内容,最后交给你。

整个过程没有安全性可言。

^footnote: 类比说明:你 = 客户端 / 浏览器、老王 = 在网络链路上的各种设备 如路由器、女神阿花 = 服务器

对称加密

终于有一天,你和女神见面了,聊起来信的内容,你们发现纸条里面的内容被别人篡改过。

于是,你们想了一个办法,把纸条上的内容通过一串密码进行加密,密码和加密方式只有你们两个知道。

这样即使信在中途被别人拆开了,他也看不懂信的内容,他不知道加密的规则,也无法伪造信的内容。

于是,你们终于可以安心的互通有无了。(写封情书都这么折腾人,难怪程序猿这个物种会注孤身~~~)

这种方式就叫做「对称加密」,而你们加密所使用的密码就叫做「对称密钥」。

^footnote: SSL 使用对称密钥 HTTP 内容进行加/解密,让 HTTP 变得看起来安全了那么一些。

虽然看起来,现在你和女神之间的通信已经可以高枕无忧了。

But !

真的是这样吗?

突然有一天,你想写信给住在老王另一个隔壁的老铁小杨,也需要通过老王来传递信件。(没错~ 隔壁老王就是这么神奇)

为了保证信件的安全,你还是需要用对称加密的方式。这就有会有几个问题:

  1. 和阿花使用过的 「对称密钥」 已经不能再次使用,不然和女神之间的通信就会有安全风险,这也就意味着你必须用新的「密钥」对信件的内容进行加密;
  2. 你并不能直接见到小杨,那你们也就无法协商 「对称密钥」和 「加密方式」。想要建立安全的通信方式,只能在「明文」的信件内,把「对称秘钥」和「加密方式」告诉小杨。如果这份信刚好被老王拆掉看过,那你和小杨之间以后的任何通信依然没有安全性可言,只是增加了「中间人」老王以后的「攻击成本」。

^footnote: 看起来不太现实的场景,在互联网 の 世界里却随处可见。

如果对称加密这么麻烦,而且有这么多问题,那怎么办呢?

非对称加密

这时候就需要用到江湖中流传已久的神器「非对称密钥」了。

「非对称加密」主要就是用来解决,如何把「对称密钥」安全的交给信息的接收人。

为了实现这个目的,你需要有一把「公钥」和一把「私钥」。

这两个「密钥」有一定的数学相关性,通俗一点讲,就是说 用「公钥」加密的内容,通过「公钥」是无法解开的。只能通过这把「公钥」对应的「私钥」才可以解开。反之, 亦然。

OK, 了解了这几个概念,接下来,我们来模拟一下场景。

你要给小杨写信,第一次你把自己的「公钥」直接写信告诉了小杨,让小杨把他的「公钥」也告诉你。中间依然由神奇的老王帮忙传递信件。双方的「公钥」老王都是知道的。

接下来,当你接受到小杨的「公钥」,就可以正式开始写信了。

首先,你准备了一个的「对称密钥」,并把信件内容通过这个「对称密钥」进行加密。

然后,用小杨给你的「公钥」,对这个加密过信件内容的「对称密钥」进行加密。

最后,把加密后的「对称密钥」& 「对称密钥」加密后的信件内容,一起交给老王。

假设,「中间人」老王想要篡改信件的内容,打开信件后,他发现信件内的两份内容都是加密过的,他尝试使用通信双方的「公钥」对两份加密的内容解密,都无法获得正确可读的内容。无奈,他只能把信件装好,交给小杨,另谋它法。

^footnote: HTTPS 协议,看起来,其实就像是「中间人」与通信双方的一场博弈。

小杨收到信件后,首先用他的「私钥」把加密后的「对称密钥」解密出来。

小杨拿到「对称密钥」后,再把信件的真实内容通过这个「对称密钥」进行解密。

于是,小杨终于能够读信了。。(求求你别再给我写信了~~~~ /(ㄒoㄒ)/~~)

^footnote: 细心的小伙伴可能会想到,干嘛不直接用「非对称加密」对正文进行加密呢?还非要先加密「对称密钥」再用「对称密钥」加密正文?这不是「脱了裤子放屁~ 多此一举吗?」直观感受上,确实是这样。但在互联网的世界里,我们往往需要兼顾安全、效率。通过上面对于对称加密和非对称加密的解释,很明显就可以发现非对称加密的算法要更复杂,效率更低,但相对安全。信息传输的正文往往是较大的文本,如果直接用非对称加密,对效率而言,无疑是的一种致命的伤害。

折腾了这么多事情,这下总该安全了吧 ?!

But !

Too Young, Too Simple!

隔壁老王,是那种甘于寂寞的人吗?

终于有一天,隔壁老王想到了一个办法,老王自己也做了一对「非对称密钥」。

当「中间人」老王把小杨的信交给你的时候,同时告诉你「小杨的 公钥 更新了,以后你用这个新的 公钥 吧」,然后老王把自己的「公钥」发给了你。你收到这个信息自然会更新小杨的「公钥」。

接下来,发生什么事情呢?大家想一下~

你用「中间人」老王伪造的「公钥」对「对称密钥」进行加密,然后把加密后的「对称密钥」和加密后的「内容」一起发送给「中间人」老王。

「中间人」老王用自己的「私钥」解密你加密后的「对称密钥」,然后用「对称密钥」解密你真实的信件。

so ~ , 信息在传输过程中,又被破解了。

数字证书

怎么办呢?

分析一下「中间人」老王 Hack 的方式。之所以可以成功,是因为你的「公钥」很容易被伪造。你无法向其他人证明这个「公钥」是你的。

正当你苦于这个问题无法解决时,当地「证书中心(CA)」发了一份通告。

你是不是在害怕自己的「公钥」被伪造?

不要怕。请把你的「公钥」以及你的个人信息告诉「证书中心(CA)」。

「证书中心(CA)」会为你的「公钥」做认证。

「证书中心(CA)」会用自己的「私钥」,对你的个人信息和「公钥」一起加密,生成「数字证书」(Digital Certificate)

有了「数字证书」,你就可以在你要发送的信件中加入你的「数字证书」。

当别人收到信件后,先用「证书中心(CA)」的「公钥」解开「数字证书」,就可以拿到你的「公钥」了。

看到这里,你想了想,如果「中间人」老王拿到携带了「数字证书」的信件。

虽然「中间人」老王也知道证书中心的「公钥」,可以用它解开「数字证书」的内容,拿到你的「公钥」。

但是,如果「中间人」老王想要替换里面的「公钥」,没有「证书中心」的「私钥」,「中间人」老王是没有办法重新生成一个收件人可识别的新的「数字证书」的。

也就是说「中间人」老王是没有办法伪造「数字证书」的,不然很容易就能被收件人发现,因为伪造的「数字证书」,用「证书中心」的「公钥」是解不开的。

这样也就保证了收件人在收到信件时,只要能用「证书中心」的「公钥」解开「数字证书」,拿到的就是「发件人」自己的「公钥」。

终于,你不需要再担心信件的内容被泄露、篡改了。

「中间人」老王发现以后想偷看信件,还需要先黑掉「证书中心(CA)」,成本太高。

生活没了兴趣,就搬走了。

连隔壁老王都走了~,这下总该安全了吧。

But !

没准哪天「证书中心(CA)」负责管理「数字证书」的员工搬到原来的隔壁老王家,碰巧他也信王!

又或者,你的书房被偷偷装上了摄像头,

当然也可能是别人家的书房。

Others

因为真实的网络环境本身要比上面送信的例子复杂的多。

所以,在互联网环境下的「HTTPS」协议的数据传输,远比上面的过程要复杂。

还会涉及到「消息摘要(Message Digest)」、「消息认证码(Message Authentication Code)」、「数字签名(Digital Signature)」、各种复杂的「加密算法」等等,所有的一切都是用来保证内容在传输过程中的安全。

说了这么多,那使用了 HTTPS 一定安全吗?

HTTPS 并非绝对安全,掌握「根证书」的机构、掌握「加密算法」的组织同样可以进行「中间人」形式的攻击。但 HTTPS 仍是现行架构下最安全的解决方案,并且它大幅增加了「中间人攻击」的成本。

对于不懂互联网的用户, 如果「Hacker」返回了一个「伪造证书」,用户信任了「电子证书」以后,「中间人」依然可以进行攻击。

[^ footnote]: 「12306」就是一个典型的案例。 它的「证书」本来就是不是由「证书机构」颁发的。对于用户而言,也就更加难以识别证书的真假了。

HTTP vs HTTPS

- HTTP HTTPS
Port 80 443
Artifacts - 需要到 CA 申请证书、构建支持 HTTPS 的服务器环境
Charge Free 按年收费,证书价格不等
Transfer 明文 加密
Performance 直接运行在 TCP 协议之上, TCP 三次握手建立连接 HTTP (应用层) 协议和 TCP (传输层) 协议之间加入了 SSL/TLS 协议,用于加密传输的内容, 除了 TCP 三次握手,还需要加上 SSL 九次握手,还有 SSL 加/解密的 CPU 运行开销
Secure 很容易被链路劫持, 盗取用户数据,篡改请求 / 响应内容 链路劫持的成本比较高,相对安全,但仍然无法防御 DNS 劫持、Client / Server 劫持
SEO 支持良好 不同浏览器支持情况不同。以国内目前的网络环境,在默认情况下,与比 HTTP 相比要差很多,不过这个问题可以通过额外的技术手段来处理,只是需要花费一些额外的成本

^footnote: HTTP / HTTPS 协议主要用于在客户端和服务器端之间做数据传输,这也就意味着 HTTPS 的安全性,只是针对本次连接中数据传输。这意味着如果你的计算机已经感染的了恶意软件,或者你已经被受到欺骗运行了某些恶意软件 — 这个世界上所有的HTTPS对于你而言也都无能为力了。

WHY

为什么需要升级 HTTPS ?

所有的「Web 安全」都倚赖你拥有了HTTPS。 如果你没有它, 那么不管你对你的密码做了多强的哈希加密,或者做了多少数据加密,攻击者都可以简单的模拟一个客户端的网络连接,读取它们的安全凭证。

国内网络环境很差,一些公共场所的路由器、小区的路由器很容易被黑客劫持。用户流量被劫持时,用户的相关信息对于「中间人劫持」而言,没有任何安全可言。无论是窃取数据或者篡改用户数据。

国内运营商内容劫持,植入广告太严重了。当然这还是比较良心的,至少运营商已经告诉了你, 你的网站很容易被黑,提醒你是时候做一些安全防范了。

上面说到 HTTPS 需要收费,但实际上并不贵。而且,对于个人或者小网站来说,「EFF (电子前沿基金会)」在 2015 年 已经推出了一个完全免费的 SSL证书 认证机构 Lets Encrypt

网站在知名搜索引擎 Google 还会对全站 HTTPS 的站点增加排名权重优先收录。(虽然在大天朝, 并没有什么卵用~)

虽然 百度 曾表示「不会主动抓取 HTTPS 网页」,但对于「很多 HTTPS 网页无法被收录」也是「耿耿于怀」。可见百度不主动抓取 HTTPS 站点也只是暂时的。

服务器性能

HTTPS 耗费 CPU 的元凶是什么?

HTTPS 确实需要更多的 CPU 来处理 SSL 连接,但这需要的处理能力对于现代计算机而言是小菜一碟了。 你会遇到 SSL 性能瓶颈的可能性完全为「0」。

目前,你更有可能在你的 Web 服务器 性能上遇到瓶颈。

用户体验

HTTPS 一定比 HTTP 慢吗?

根据网上的一些资料,刚刚搭建的 HTTPS 的站点通常会比 HTTP 的站点慢 15% 左右。

慢的主要原因是在第一次访问时, 需要使用非对称加密进行验证。

验证成功之后,后续的连接,就可以直接使用「对称加密」的方式进行沟通。

站点的访问速度是可以通过具体可行的方案进行优化的。

所以, HTTPS 实际上对用户的影响并不明显。

[^ footnote]: 通过专业的优化手段,HTTPSHTTP 在性能上和用户体验上的问题,几乎可以忽略。更何况,业界已经有很多优秀、成熟的方案可以参考。

WHO

是否应该升级 HTTPS 呢?

虽然谷歌和百度都对 HTTPS 「另眼相看」,但这并不意味着我们都应该把网站协议转换成 HTTPS

如果是个人博客、宣传类网站之类的话,则可不必跟风而行。

毕竟采用 HTTPS 协议是要多浪费一些精力的,而且在某些情况下,也不利于网站的 SEO 工作。

如果网站类型属于电子商务、金融、社交网络、资讯信息网站、新闻网站等涉及到用户信息、操作行为、隐私的话,采用 HTTPS 协议自然是最好的。

作为服务的提供者,我们必须要承担起保护用户的重任。

要做到这一点,方法之一就是强制使用HTTPS、

WHEN

什么时候做 HTTPS 好呢?

As Soon As Possibly !

HOW

如何申请 HTTPS 证书呢?

如何选择证书?

请自行相关查阅资料

如何将自己的站点迁移到 HTTPS 呢?

服务器改造

运维改造
  • 购买证书

略过

  • 配置服务器环境

略过

域名改造
方案

收敛域名。一方面可以简化技术架构的复杂度。另一方面也是出于性能的考虑。

HTTPS 场景下,多域名带来更多的 TLS 握手,会降低服务端和客户端的性能。

页面改造
方案

如果当前资源或页面跳转只支持 HTTPHTTPS 协议,则使用支持的协议

如果需要资源同时 HTTPHTTPS 协议,需自动适配

  • 静态资源的URL,采用 // 引用资源,表示遵从当前页面的协议,浏览器会进行自动补全。
  • 动态数据中的URL,根据发起请求的协议,返回数据中的URL自动补全为请求时的协议。
缺点
  1. 有些老的移动终端对 “//“ 解析不支持
  2. 一些 JS 可能会引用 http:// 的资源
  3. SEO 待确认,搜索引擎对 // 链接的支持还不确定
典型案例

在老版本的 医学时间 App 有一个页面,是通过 file:// 协议加载的页面代码。

在这个页面代码中,会动态的输出一段服务器输出的 JS 脚本。

JS 脚本会动态加载腾讯云提供的静态资源。

而腾讯云的JS 脚本,为了兼容客户的不同协议,在脚本加载时,使用 //xxx.com/xx.js

于是,悲剧就发生了。

检测 HTTPS 的配置的评分

请到 SSL Abs

生产环境中的使用

这里介绍下在生产环境中关于 HTTPS 的使用。

生产环境中,CA 签发的证书被配置在前端服务器 nginx 的集群上。

简易的 HTTPS 应用架构图

为什么不直接配置在应用服务器上呢?

服务器资源对于应用服务器而言,本身就是一种稀缺的资源。

如果在应用服务器上直接配置 SSL 证书,这就意味着所有客户端连接的建立、以及数据加解密的资源损耗,全部需要由应用服务器来承担,在连接较少的时候,可能影响还不大,如果连接多了起来,这无疑会压垮服务器,最后导致整个业务服务 Unavailable。

这就好像,你去参加马拉松,比赛开始给自己加了 5 公斤的负重,刚开始跑,感觉还 OK,但跑得久了,就会发现自己根本无法承载这么高的负荷。很可能,在半路被抬到医院急救。「 No Zuo No Die ~ 」

这里要稍微解释一下前端服务器 nginx,作为一款反向代理服务器。

它主要的作用是用来与客户端建立请求,并将请求转发到应用服务器,最后将应用服务器的响应返回给客户端。

作为客户端与服务器的「代理服务器」,它可以帮助我们处理一些简单的服务器负载均衡、请求的重写等等。

通过它起到的作用,我们大致可以发现,它对于服务器资源的使用其实并不多。

无需要复杂的数据运算、业务运算。

无需在内存中记录的业务数据,最多也只去存储一些页面缓存。

由于 nginx 支持异步非阻塞的网络 I/O 模型, 即使在高并发的情况下,它依然能保持低资源低消耗高性能。

所以,把 SSL 证书配置在前端服务器 nginx 上,再由 nginxhttps 的请求以 http 协议的形式转发给应用服务器,无疑是资源最优化使用的方案。

而且,基于 nginx 本身的特性,我们还可以直接在 nginx 本身制定一些 https 的处理策略。比如:强制客户端 http 请求重定向到 https、如果发现请求来自于百度爬虫,把 https 请求重定向到 http 解决 SEO 的问题等。

如果客户端 HTTPS 连接过多,导致前端服务器 nginx CPU 资源耗尽,我们也只需扩展 nginx 集群即可。

^footnote: 「服务器资源:泛指服务器硬件资源,比如 CPU、内存等」、「应用服务器:泛指Web 业务应用」

FUTURE

除了 HTTPS, 我们还有什么可选的方案吗?

SPDY

2012 年,Google 综合了 HTTPSHTTP 两者的优点,提出了 SPDY 的方案。

SPDY 基于 HTTPS 环境。

HTTP 2.0

2015 年 5 月, IETF 官方的 HTTP/2 标准的正式发表。 主要基于 SPDY 协议。

HTTP/2 只在 HTTPS 环境下被支持。

EOF


About HTTPS!
http://kenneth-hao.github.io/2017/05/15/about-https/
作者
Yuewen
发布于
2017年5月16日
许可协议