协议安全和加密越来越引起人们的重视和关注,今天就跟大家分享一点协议加密方面的知识。要说清楚 HTTPS 协议的实现原理,至少需要如下几个背景知识。
大致了解几个基本术语(HTTPS、SSL、TLS)的含义大致了解 HTTP 和 TCP 的关系(尤其是 短连接VS长连接)大致了解加密算法的概念(尤其是 对称加密与非对称加密 的区别)大致了解 CA 证书的用途考虑到很多技术菜鸟可能不了解上述背景,俺先用最简短的文字描述一下。如果你自认为不是菜鸟,请略过本章节,直接去看 HTTPS 协议的需求。
一、先澄清几个术语——HTTPS、SSL、TLS。
1. HTTP 是干嘛用滴?
首先,HTTP 是一个网络协议,是专门用来帮你传输 Web 内容滴。关于这个协议,就算你不了解,至少也听说过吧?比如你访问俺的博客的主页,浏览器地址栏会出现如下的网址http://www.xxx.com/
俺加了粗体的部分就是指 HTTP 协议。大部分网站都是通过 HTTP 协议来传输 Web 页面、以及 Web 页面上包含的各种东东(图片、CSS 样式、JS 脚本)。
2. SSL/TLS 是干嘛用滴?
SSL 是洋文 Secure Sockets Layer 的缩写,中文叫做 安全套接层。它是在上世纪 90 年代中期,由网景公司设计的。(顺便插一句,网景公司不光发明了 SSL,还发明了很多 Web 的基础设施——比如CSS 样式表 和JS 脚本) 为啥要发明 SSL 这个协议捏?因为原先互联网上使用的 HTTP 协议是明文的,存在很多缺点——比如传输内容会被偷窥(嗅探)和篡改。发明 SSL 协议,就是为了解决这些问题。
到了 1999 年,SSL 因为应用广泛,已经成为互联网上的事实标准。IETF 就在那年把 SSL 标准化。标准化之后的名称改为 TLS(是 Transport Layer Security 的缩写),中文叫做传输层安全协议。
很多相关的文章都把这两者并列称呼(SSL/TLS),因为这两者可以视作同一个东西的不同阶段。
3. HTTPS 是啥意思?
解释完 HTTP 和 SSL/TLS,现在就可以来解释 HTTPS 啦。咱们通常所说的 HTTPS 协议,说白了就是 HTTP 协议 和SSL/TLS 协议的组合。你可以把 HTTPS 大致理解为——HTTP over SSL或HTTP over TLS(反正 SSL 和 TLS 差不多)。
二、再来说说 HTTP 协议的特点
作为背景知识介绍,还需要再稍微谈一下 HTTP 协议本身的特点。HTTP 本身有很多特点,考虑到篇幅有限,俺只谈那些和 HTTPS 相关的特点。
1. HTTP 的版本和历史
如今咱们用的 HTTP 协议,版本号是 1.1(也就是 HTTP 1.1)。这个 1.1 版本是 1995 年底开始起草的(技术文档是 RFC2068),并在 1999 年正式发布(技术文档是 RFC2616)。
在 1.1 之前,还有曾经出现过两个版本 0.9 和 1.0,其中的 HTTP 0.9 没有被广泛使用,而 HTTP 1.0 被广泛使用过。另外,2015年IETF 就要发布 HTTP 2.0 的标准了。
2. HTTP 和 TCP 之间的关系
简单地说,TCP 协议是 HTTP 协议的基石——HTTP 协议需要依靠 TCP 协议来传输数据。在网络分层模型中,TCP 被称为 传输层协议,而 HTTP 被称为 应用层协议。
有很多常见的应用层协议是以 TCP 为基础的,比如 FTP、SMTP、POP、IMAP 等。
TCP 被称为 面向连接 的传输层协议。关于它的具体细节,俺就不展开了(否则篇幅又失控了)。你只需知道:传输层主要有两个协议,分别是 TCP 和 UDP。TCP 比 UDP 更可靠。你可以把 TCP 协议想象成某个水管,发送端这头进水,接收端那头就出水。并且 TCP 协议能够确保,先发送的数据先到达(与之相反,UDP 不保证这点)。
3. HTTP 协议如何使用 TCP 连接?
HTTP 对 TCP 连接的使用,分为两种方式:俗称 短连接 和长连接(长连接又称 持久连接,洋文叫做Keep-Alive 或Persistent Connection) 假设有一个网页,里面包含好多图片,还包含好多外部的CSS 文件和 JS 文件。在 短连接 的模式下,浏览器会先发起一个 TCP 连接,拿到该网页的 HTML 源代码(拿到 HTML 之后,这个 TCP 连接就关闭了)。然后,浏览器开始分析这个网页的源码,知道这个页面包含很多外部资源(图片、CSS、JS)。
然后针对每一个外部资源,再分别发起一个个 TCP 连接,把这些文件获取到本地(同样的,每抓取一个外部资源后,相应的 TCP 就断开) 相反,如果是 长连接 的方式,浏览器也会先发起一个 TCP 连接去抓取页面。但是抓取页面之后,该 TCP 连接并不会立即关闭,而是暂时先保持着(所谓的Keep-Alive)。然后浏览器分析 HTML 源码之后,发现有很多外部资源,就用刚才那个 TCP 连接去抓取此页面的外部资源。
在 HTTP 1.0 版本,默认使用的是 短连接(那时候是 Web 诞生初期,网页相对简单,短连接 的问题不大);到了 1995 年底开始制定 HTTP 1.1 草案的时候,网页已经开始变得复杂(网页内的图片、脚本越来越多了)。这时候再用短连接的方式,效率太低下了(因为建立 TCP 连接是有 时间成本 和CPU 成本滴)。
所以,在 HTTP 1.1 中,默认采用的是 Keep-Alive 的方式。关于 Keep-Alive 的更多介绍,可以参见维基百科词条。
三、谈谈 对称加密 和非对称加密的概念
1. 啥是 加密 和解密?
通俗而言,你可以把 加密 和解密理解为某种互逆的数学运算。就好比 加法和减法 互为逆运算、乘法和除法互为逆运算。
加密的过程,就是把 明文 变成 密文 的过程;反之,解密的过程,就是把 密文 变为明文。在这两个过程中,都需要一个关键的东东——叫做密钥——来参与数学运算。
2. 啥是 对称加密?
所谓的 对称加密技术,意思就是说:加密 和解密使用相同的密钥。这个比较好理解。就好比你用 7zip 或 WinRAR 创建一个带密码(口令)的加密压缩包。当你下次要把这个压缩文件解开的时候,你需要输入同样的密码。在这个案列中,密码 / 口令就如同刚才说的密钥。
3. 啥是 非对称加密?
所谓的 非对称加密技术,意思就是说:加密 和解密使用不同的密钥。这玩意儿比较难理解,也比较难想到。当年 非对称加密 的发明,还被誉为 密码学 历史上的一次革命。
由于篇幅有限,对 非对称加密 这个话题,俺就不展开了。有空的话,再单独写一篇扫盲。
4. 各自有啥优缺点?
看完刚才的定义,很显然:(从功能角度而言)非对称加密能干的事情比 对称加密 要多。这是 非对称加密 的优点。但是 非对称加密 的实现,通常需要涉及到 复杂数学问题。所以,非对称加密 的性能通常要差很多(相对于 对称加密 而言)。这两者的优缺点,也影响到了 SSL 协议的设计。
四、HTTPS 协议的需求是啥?
花了好多口水,终于把背景知识说完了。下面正式进入正题。先来说说当初设计 HTTPS 是为了满足哪些需求?
很多介绍 HTTPS 的文章一上来就给你讲实现细节。个人觉得:这是不好的做法。早在 2009 年开博的时候,发过一篇<学习技术的三部曲:WHAT、HOW、WHY>,其中谈到 WHY 型问题 的重要性。一上来就给你讲协议细节,你充其量只能知道 WHAT 和 HOW,无法理解 WHY。
俺在前一个章节讲了背景知识,在这个章节讲了需求,这就有助于你理解:当初为什么要设计成这样?——这就是 WHY 型的问题。
兼容性
因为是先有 HTTP 再有 HTTPS。所以,HTTPS 的设计者肯定要考虑到对原有 HTTP 的兼容性。这里所说的兼容性包括很多方面。比如已有的 Web 应用要尽可能无缝地迁移到 HTTPS;比如对浏览器厂商而言,改动要尽可能小;基于 兼容性 方面的考虑,很容易得出如下几个结论:
HTTPS 还是要基于 TCP 来传输(如果改为 UDP 作传输层,无论是 Web 服务端还是浏览器客户端,都要大改,动静太大了)。单独使用一个新的协议,把 HTTP 协议包裹起来 (所谓的 HTTP over SSL,实际上是在原有的 HTTP 数据外面加了一层 SSL 的封装。HTTP 协议原有的 GET、POST 之类的机制,基本上原封不动)。打个比方:如果原来的 HTTP 是塑料水管,容易被戳破;那么如今新设计的 HTTPS 就像是在原有的塑料水管之外,再包一层金属水管。一来,原有的塑料水管照样运行;二来,用金属加固了之后,不容易被戳破。
可扩展性
前面说了,HTTPS 相当于是 HTTP over SSL。如果 SSL 这个协议在 可扩展性 方面的设计足够牛逼,那么它除了能跟 HTTP 搭配,还能够跟其它的应用层协议搭配。岂不美哉?
现在看来,当初设计 SSL 的人确实比较牛。如今的 SSL/TLS 可以跟很多常用的应用层协议(比如: FTP、SMTP、POP、Telnet)搭配,来强化这些应用层协议的安全性。
接着刚才打的比方:如果把 SSL/TLS 视作一根用来加固的金属管,它不仅可以用来加固输水的管道,还可以用来加固输煤气的管道。
保密性
HTTPS 需要做到足够好的保密性。说到保密性,首先要能够对抗嗅探(行话叫 Sniffer)。所谓的 嗅探,通俗而言就是监视你的网络传输流量。如果你使用明文的 HTTP 上网,那么监视者通过嗅探,就知道你在访问哪些网站的哪些页面。
嗅探是最低级的攻击手法。除了嗅探,HTTPS 还需要能对抗其它一些稍微高级的攻击手法——比如 重放攻击。
完整性
除了 保密性,还有一个同样重要的目标是确保完整性。关于完整性 这个概念,在之前的博文<扫盲文件完整性校验——关于散列值和数字签名>中大致提过。健忘的同学再去温习一下。在发明 HTTPS 之前,由于 HTTP 是明文的,不但容易被嗅探,还容易被篡改。
举个案列:比如咱们天朝的网络运营商都比较流氓,经常有网友抱怨说访问某网站(本来是没有广告的),竟然会跳出很多广告。为啥会这样捏?因为你的网络流量需要经过 ISP 的线路才能到达公网。如果你使用的是明文的 HTTP,ISP 很容易就可以在你访问的页面中植入广告。所以,当初设计 HTTPS 的时候,还有一个需求是 确保 HTTP 协议的内容不被篡改。
真实性
在谈到 HTTPS 的需求时,真实性经常被忽略。其实 真实性 的重要程度不亚于前面的 保密性 和完整性。
举个案列:你因为使用网银,需要访问该网银的 Web 站点。那么,你如何确保你访问的网站确实是你想访问的网站?(这话有点绕口令) 有些天真的同学会说:通过看网址里面的域名来确保。
为啥说这样的同学是 天真的?因为 DNS 系统本身是不可靠的(尤其是在设计 SSL 的那个年代,连DNSSEC 都还没发明)。由于DNS 的不可靠(存在域名欺骗 和域名劫持),你看到的网址里面的域名未必是真实滴!所以,HTTPS 协议必须有某种机制来确保 真实性 的需求。
性能
再来说最后一个需求——性能。引入 HTTPS 之后,不能导致性能变得太差。否则的话,谁还愿意用?为了确保性能,SSL的设计者至少要考虑如下几点:
如何选择加密算法(对称or非对称)?如何兼顾 HTTP 采用的 短连接TCP 方式?SSL 是在1995 年之前开始设计的,那时候的 HTTP 版本还是 1.0,默认使用的是 短连接 的 TCP 方式——默认不启用 Keep-Alive)。