https

需求

“人们最初设计互联网时,很少考虑到安全。这样的结果是,核心通信协议本质上是不安全的,只能依靠所有参与方的诚信行为。互联网在早期由少数节点(大部分是大学)构成,那时这也许行得通;但现在所有人都可以连接到互联网,这种方式便土崩瓦解。”

因此要有一种加密方式在基于不安全的基础设施提供安全通信。这种方式要能解决安全的三个核心要求:保持秘密(机密性)、验证身份(真实性)、完整性(不会在传输过程中被篡改)

术语——HTTPS、SSL、TLS

SSL 是洋文“Secure Sockets Layer”的缩写,中文叫做“安全套接层”。它是在上世纪90年代中期,由网景公司设计的。(顺便插一句,网景公司不光发明了 SSL,还发明了很多 Web 的基础设施——比如“CSS 样式表”和“JS 脚本”)

为啥要发明 SSL 这个协议捏?因为原先互联网上使用的 HTTP 协议是明文的,存在很多缺点——比如传输内容会被偷窥(嗅探)和篡改。发明 SSL 协议,就是为了解决这些问题。

到了1999年,SSL 因为应用广泛,已经成为互联网上的事实标准。IETF 就在那年把 SSL 标准化。标准化之后的名称改为 TLS(是“Transport Layer Security”的缩写),中文叫做“传输层安全协议”。

很多相关的文章都把这两者并列称呼(SSL/TLS),因为这两者可以视作同一个东西的不同阶段。

◇ “HTTPS”是啥意思?

解释完 SSL/TLS,现在就可以来解释 HTTPS 啦。咱们通常所说的 HTTPS 协议,说白了就是“HTTP 协议”和“SSL/TLS 协议”的组合。你可以把 HTTPS 大致理解为——“HTTP over SSL”或“HTTP over TLS”(反正 SSL 和 TLS 差不多)。

SSL成为标准之后的网络通信的理论模型:开放系统互联(open systems interconnection, OSI)模型
如下表格:

层号 OSI层 描述 协议实例
7 应用层 应用数据 HTTP、SMTP、IMAP
6 表示层 数据表示、转换和加密 SSL/TLS
5 会话层 多连接管理 -
4 传输层 包或流的可靠传输 TCP、UDP
3 网络层 网络节点间的路由与数据分发 IP、IPSec
2 数据链路层 可靠的本地数据连接(LAN) 以太网
1 物理层 直接物理数据连接(电缆) CAT5

更简单的图示:

image.png

由上可知整个https的核心是SSL/TLS协议

SSL/TLS协议的握手过程

SSL/TLS协议的基本思路是采用公钥加密法,也就是说,客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密。

握手在实际操作中会遇到两个问题:
(1)握手中服务器将公钥发送给客户端的时候如何保证公钥不被篡改?

解决方法:将公钥放在数字证书中。只要证书是可信的,公钥就是可信的。

(2)公钥加密计算量太大,如何减少耗用的时间?

解决方法:每一次对话(session),客户端和服务器端都生成一个"对话密钥"(session key),用它来加密信息。由于"对话密钥"是对称加密,所以运算速度非常快,而服务器公钥只用于加密"对话密钥"本身,这样就减少了加密运算的消耗时间。

◇ SSL/TLS协议的基本过程

开始加密通信之前,客户端和服务器首先必须建立连接和交换参数,这个过程叫做握手(handshake)。
假定客户端叫做爱丽丝,服务器叫做鲍勃,整个握手过程分成五步:

第一步,爱丽丝给出协议版本号、一个客户端生成的随机数(Client random),以及客户端支持的加密方法。
第二步,鲍勃确认双方使用的加密方法,并给出数字证书、以及一个服务器生成的随机数(Server random)。
第三步,爱丽丝确认数字证书有效,然后生成一个新的随机数(Premaster secret),并使用数字证书中的公钥,加密这个随机数,发给鲍勃。
第四步,鲍勃使用自己的私钥,获取爱丽丝发来的随机数(即Premaster secret)。
第五步,爱丽丝和鲍勃根据约定的加密方法,使用前面的三个随机数,生成"对话密钥"(session key),用来加密接下来的整个对话过程。

上面的五步,画成一张图,就是下面这样。

image.png

再次强调:
1 为了数据安全的目的引入数据加密
2 公钥加密法用来协商对称加密的对话密钥
3 协商前要将公钥加密法的公钥发送给客户端,为了保证公钥不被篡改、替换,需要证书的协助
所以服务关系为:证书->公钥加密法公钥发送->协商对称加密的回话密钥->数据传输加密

加密

◇ 啥是“加密”和“解密”?

通俗而言,你可以把“加密”和“解密”理解为某种【互逆的】数学运算。就好比“加法和减法”互为逆运算、“乘法和除法”互为逆运算。

“加密”的过程,就是把“明文”变成“密文”的过程;反之,“解密”的过程,就是把“密文”变为“明文”。在这两个过程中,都需要一个关键的东东——叫做“密钥”——来参与数学运算。

◇ 啥是“对称加密”?

所谓的“对称加密技术”,意思就是说:“加密”和“解密”使用【相同的】密钥。这个比较好理解。就好比你用 7zip 或 WinRAR 创建一个带密码(口令)的加密压缩包。当你下次要把这个压缩文件解开的时候,你需要输入【同样的】密码。在这个例子中,密码/口令就如同刚才说的“密钥”。

◇ 啥是“非对称加密”?

所谓的“非对称加密技术”,意思就是说:“加密”和“解密”使用【不同的】密钥。想具体了解密钥交换算法的同学可参考这篇文章:扫盲 HTTPS 和 SSL/TLS 协议[3]:密钥交换(密钥协商)算法及其原理

◇ 各自有啥优缺点?

看完刚才的定义,很显然:(从功能角度而言)“非对称加密”能干的事情比“对称加密”要多。这是“非对称加密”的优点。但是“非对称加密”的实现,通常需要涉及到“复杂数学问题”。所以,“非对称加密”的性能通常要差很多(相对于“对称加密”而言)。

这两者的优缺点,也影响到了 SSL 协议的设计。

◇ 加密方式可行性

★方案1——单纯用“对称加密算法”的可行性

首先简单阐述一下,“单纯用对称加密”为啥是【不可行】滴。

如果“单纯用对称加密”,浏览器和网站之间势必先要交换“对称加密的密钥”。

如果这个密钥直接用【明文】传输,很容易就会被第三方(有可能是“攻击者”)偷窥到;如果这个密钥用密文传输,那就再次引入了“如何交换加密密钥”的问题——这就变成“先有鸡还是先有蛋”的循环逻辑了。

所以,【单纯用】对称加密,是没戏滴。

★方案2——单纯用“非对称加密算法”的风险

说完“对称加密”,再来说说“非对称加密”。“加密和解密采用不同的密钥”。基于这个特点,可以避开前面提到的“循环逻辑”的困境。大致的步骤如下:

第1步
网站服务器先基于“非对称加密算法”,随机生成一个“密钥对”(为叙述方便,称之为“k1 和 k2”)。因为是随机生成的,目前为止,只有网站服务器才知道 k1 和 k2。

第2步
网站把 k1 保留在自己手中,把 k2 用【明文】的方式发送给访问者的浏览器。
因为 k2 是明文发送的,自然有可能被偷窥。不过不要紧。即使偷窥者拿到 k2,也【很难】根据 k2 推算出 k1
(这一点是由“非对称加密算法”从数学上保证的)。

第3步
浏览器拿到 k2 之后,先【随机生成】第三个对称加密的密钥(简称 k)。
然后用 k2 加密 k,得到 k'(k' 是 k 的加密结果)
浏览器把 k' 发送给网站服务器。

由于 k1 和 k2 是成对的,所以只有 k1 才能解密 k2 的加密结果。
因此这个过程中,即使被第三方偷窥,第三方也【无法】从 k' 解密得到 k

第4步
网站服务器拿到 k' 之后,用 k1 进行解密,得到 k
至此,浏览器和网站服务器就完成了密钥交换,双方都知道 k,而且【貌似】第三方无法拿到 k
然后,双方就可以用 k 来进行数据双向传输的加密。

但是“方案2”依然是不安全滴——虽然“方案2”可以在一定程度上防止网络数据的【偷窥/嗅探】,但是【无法】防范网络数据的【篡改】。

假设有一个攻击者处于“浏览器”和“网站服务器”的通讯线路之间,并且这个攻击者具备“修改双方传输数据”的能力。那么,这个攻击者就可以攻破“方案2”。具体的攻击过程如下:

第1步
这一步跟原先一样——服务器先随机生成一个“非对称的密钥对”k1 和 k2(此时只有网站知道 k1 和 k2)

第2步
当网站发送 k2 给浏览器的时候,攻击者截获 k2,保留在自己手上。
然后攻击者自己生成一个【伪造的】密钥对(以下称为 pk1 和 pk2)。
攻击者把 pk2 发送给浏览器。

第3步
浏览器收到 pk2,以为 pk2 就是网站发送的。
浏览器不知情,依旧随机生成一个对称加密的密钥 k,然后用 pk2 加密 k,得到密文的 k'
浏览器把 k' 发送给网站。
(以下是关键)
发送的过程中,再次被攻击者截获。
因为 pk1 pk2 都是攻击者自己生成的,所以攻击者自然就可以用 pk1 来解密 k' 得到 k
然后,攻击者拿到 k 之后,用之前截获的 k2 重新加密,得到 k'',并把 k'' 发送给网站。

第4步
网站服务器收到了 k'' 之后,用自己保存的 k1 可以正常解密,所以网站方面不会起疑心。
至此,攻击者完成了一次漂亮的偷梁换柱,而且让双方都没有起疑心。

上述过程,也就是传说中大名鼎鼎的“中间人攻击”。洋文叫做“Man-In-The-Middle attack”。缩写是 MITM。

为了更加形象,补充两张示意图,分别对应“偷窥模式”和“中间人模式”。让你更直观地体会两者的差异。

image.png

★方案2失败的根源——缺乏【可靠的】身份认证

为啥“方案2”会失败?

除了在图中提到的“攻击者具备篡改数据的能力”,还有另一点关键点——“方案2缺乏身份认证机制”。

正是因为“缺乏身份认证机制”,所以当攻击者一开始截获 k2 并把自己伪造的 pk2 发送给浏览器时,浏览器无法鉴别:自己收到的密钥是不是真的来自于网站服务器。

假如具备某种【可靠的】身份认证机制,即使攻击者能够篡改数据,但是篡改之后的数据很容易被识破。那篡改也就失去了意义。

身份认证的几种方式

下面,来介绍几种常见的“身份认证原理”。

◇ 基于某些“私密的共享信息”

为了解释“私密的共享信息”这个概念,咱们先抛开“信息安全”,谈谈日常生活中的某个场景。

假设你有一个久未联系的老朋友。因为时间久远,你已经没有此人的联系方式了。某天,此人突然给你发了一封电子邮件。

那么,你如何确保——发邮件的人确实是你的老朋友捏?

有一个办法就是:你用邮件向对方询问某个私密的事情(这个事情只有你和你的这个朋友知道,其他人不知道)。如果对方能够回答出来,那么对方【很有可能】确实是你的老朋友。

从这个例子可以看出,如果通讯双方具有某些“私密的共享信息”(只有双方知道,第三方不知道),就能以此为基础,进行身份认证,从而建立信任。

◇ 基于双方都信任的“公证人”

“私密的共享信息”,通常需要双方互相比较熟悉,才行得通。如果双方本来就互不相识,如何进行身份认证以建立信任关系捏?

这时候还有另一个办法——依靠双方都信任的某个“公证人”来建立信任关系。

如今 C2C 模式的电子商务,其实用的就是这种方式——由电商平台充当公证人,让买家与卖家建立某种程度的信任关系。

考虑到如今的网购已经相当普及,大伙儿应该对这类模式很熟悉吧。所以俺就不浪费口水了。

◇ CA 的引入——如何解决 SSL 的身份认证问题

说完身份认证的方式/原理,再回到 SSL/TLS 的话题上。对于 SSL/TLS 的应用场景,由于双方(“浏览器”和“网站服务器”)通常都是互不相识的,显然不可能采用第一种方式(私密的共享信息),而只能采用第二种方式(依赖双方都信任的“公证人”)。那么,谁来充当这个公证人捏?这时候,CA 就华丽地登场啦。所谓的 CA,就是“数字证书认证机构”的缩写,洋文全称叫做“Certificate Authority”。

服务端先从CA那里购买一个数字证书,证书里包含了服务端的公钥。客户端请求时将证书发给客户端,客户端验证证书是否可信。如果可信就拿认为其中的公钥是来自服务端的,可以使用。文章最后会详细讲解CA和CA证书

★基于 CA 证书进行密钥交换
所谓的数字证书,技术上依赖的还是前面提到的“非对称加密”。为了描述“CA 证书”在 SSL/TLS 中的作用,俺大致说一下原理(仅仅是原理,具体的技术实现要略复杂些)

第1步(这是“一次性”的准备工作)
网站方面首先要花一笔银子,在某个 CA 那里购买一个数字证书。该证书通常会对应几个文件:其中一个文件包含公钥,还有一个文件包含私钥。此处的“私钥”,相当于“方案2”里面的 k1;而“公钥”类似于“方案2”里面的 k2。网站方面必须在 Web 服务器上部署这两个文件。所谓的“公钥”,顾名思义就是可以公开的 key;而所谓的“私钥”就是私密的 key。其实前面已经说过了,这里再唠叨一下:“非对称加密算法”从数学上确保了——即使你知道某个公钥,也很难(不是不可能,是很难)根据此公钥推导出对应的私钥。
第2步
当浏览器访问该网站,Web 服务器首先把包含公钥的证书发送给浏览器。
第3步
浏览器验证网站发过来的证书。如果发现其中有诈,浏览器会提示“CA 证书安全警告”。由于有了这一步,就大大降低了(注意:是“大大降低”,而不是“彻底消除”)前面提到的“中间人攻击”的风险。为啥浏览器能发现 CA 证书是否有诈?因为正经的 CA 证书,都是来自某个权威的 CA。如果某个 CA 足够权威,那么主流的操作系统(或浏览器)会内置该 CA 的“根证书”。(比如 Windows 中就内置了几十个权威 CA 的根证书)因此,浏览器就可以利用系统内置的根证书,来判断网站发过来的 CA 证书是不是某个 CA 颁发的。(关于“根证书”和“证书信任链”的概念,请参见之前的教程《数字证书及CA的扫盲介绍》)
第4步
如果网站发过来的 CA 证书没有问题,那么浏览器就从该 CA 证书中提取出“公钥”。然后浏览器随机生成一个“对称加密的密钥”(以下称为 k)。用 CA 证书的公钥加密 k,得到密文 k'浏览器把 k' 发送给网站。
第5步
网站收到浏览器发过来的 k',用服务器上的私钥进行解密,得到 k。至此,浏览器和网站都拥有 k,“密钥交换”大功告成啦。

至此终于将公钥安全送达浏览器手中,完成了身份认证。

数字签名和CA

◇ 数字签名

数字签名是使用非对称加密来确保消息或其他数据的完整性的一种方式。签名人必须有一个数字身份包括:一对公私钥和相应的证明签名者公钥真实性的数字证书。

签名者首先计算文件摘要(例如Hash函数)然后私钥加密摘要,生成签名。将签名附在加密的文件中发送给收件人,将解密的公钥放到证书中也发送给收件人。

收件人用相同的算法计算文件摘要,然后用证书中的公钥解密加密的摘要,如果两个摘要相同则证明消息并没有被更改并且由密钥的所有者发送。

创建数字签名:


image.png

验证数字签名:


image.png

这里有个问题就是如果文件被中间人更改,用自己的私钥签名,然后同时替换了签名和证书,收件人用中间人发送来的公钥解密中间人对文件的签名,依然可以验证通过,但是文件已经被更改了啊。

因此为了证明签名提供者就是他声明的那个人(不是中间人冒充的),证书也需要被签名,此类证书也由签发证书的认证机构签字。

也即是说证书提供的身份认证机制依赖于数字签名。证书的数字签名确保证书不能够被中间人更改。

◇ CA对数字证书签名

★数字证书
数字证书是用于验证证书的持有人或发件人身份的数据集合。
例如,X.509证书包含以下信息:

  • 结构信息版本,序列号,用于创建签名的消息摘要算法等等

  • 来自证书颁发机构(CA)的数字签名 - 颁发证书的个人或组织 - 以确保证书未被更改,并指示发行人(CA)的身份

  • 有关证书持有人姓名,电子邮件地址,公司名称,所有者公钥等的信息

  • 有效期(证书在此期间之前或之后无效)

  • 证书扩展 -包含其他信息的属性,例如此证书的允许用途


    image.png

每个证书都是由另一个证书签名的,由此产生了一个证书信任链,链中的每个证书都由下一个证书进行数字签名,直到根证书,根证书的所有者成为根证书颁发机构

根证书是自签名的,意思是根证书的签名是由根证书颁发机构自己创建使用自己的私钥签名。

根证书颁发机构创建自己的证书然后创建中间证书颁发机构的证书

★ 证书的创建
根证书:

  1. 根证书颁发机构首先创建一对公私钥
  2. 创建证书,先将公钥填进证书,然后计算证书摘要,用私钥加密摘要生成签名,并将签名附到证书中。 根证书创建完成

根证书颁发机构创建中间证书颁发机构的证书:

  1. 中间颁发机构生成自己的一对公私钥
  2. 创建证书,将公钥填进证书,将证书发送给根证书颁发机构申请签名
  3. 根证书颁发机构计算中间颁发机构发来证书的摘要,用自己的私钥加密摘要生成签名,并将签名附到证书中
  4. 根证书颁发机构还在该证书中填写了自己的机构信息以声明这张证书是我签名的,以后需要验证这张证书的真伪的时候需要用到我的证书

最终用户证书的生成需要中间证书颁发机构签名,流程和中间证书的生成类似。

image.png

用户使用最终用户证书给文档签名,用户服务端用私钥对文档签名,公钥在证书中,证书发给用户客户端,客户端用先验证证书的真实性,然后用证书中的公钥解密摘要验证文档的完整性。

image.png

★证书的验证
客户端拿到证书以后使用证书中的公钥之前,要验证证书的真实性

证书的验证过程就是沿着证书创建过程中产生的证书链回溯到根证书的过程

  1. 根据证书中包含的签名颁发机构信息获取上一级的证书,获取整个证书链
  2. 根证书的公钥解密中间证书中的签名得到摘要s,计算中间证书的摘要t,对比s和t,如果一致中间证书可信,否则不可信,验证通不过
  3. 中间证书验证通过后,用中间证书中的公钥解密最终用户证书的签名得到摘要k,计算最终用户的摘要m,对比k和m,如果一致则最终用户证书可信,否则验证通不过

上边验证了中间证书和最终用户证书的真实性,但是根证书呢?还没验证根证书的真实性呢,根证书是自签名的,用根证书中的公钥永远能解开他自己的签名,怎么验证?

从算法逻辑上没法验证根证书的真实性了。

实际上,根证书是靠操作系统验证真实性的。操作系统中维护了一个证书列表,各大CA机构的根证书都在其中,表示操作系统信任这个列表中的所有证书(点击查看iOS or macOS信任的根证书列表),证书验证的时候会查看根证书是否在系统信任更证书列表里,如果在,根证书就可信任,然后验证中间证书和最终用户证书。

系统信任根证书列表是会变动的:新的CA达到系统信任级别或者已存在的CA变得不可信任。

关于证书这一块,个人理解感觉也有偏差,可以查看大神写的数字证书及 CA 的扫盲介绍

总结

终于对https有了大体的了解

本文大量引(抄)用(袭)了扫盲 HTTPS 和 SSL/TLS 协议[0]:引子列出文章的内容,通过这个引子里的相关文章,才算对https有了体会。深表感谢。虽然大量抄袭并且改动了一些导致没有原文讲的好,有兴趣的同学可以直接去阅读原文,我只是想把不明白的地方搞明白然后做个记录。

下篇笔记iOS开发中对https的处理开始学习一下NSURLSession中对https的处理.

参考:
扫盲 HTTPS 和 SSL/TLS 协议[0]:引子
图解SSL/TLS协议
SSL/TLS协议运行机制的概述
《HTTPS权威指南》
Cryptography Concepts In Depth

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容