HTTPS 原理浅析

前言

我们在网上进行业务的时候会发现,涉及金融、支付、登录、后台等敏感业务的网站,都会自动跳转到  https:// 这样的开头。

不同的网站,浏览器会给出不同的提示,如下图所示:

15302828091822337

  • 地址为灰色,表示网站未加密,使用 HTTP 协议,易被中间人截获信息。
  • 地址为红色,虽然使用 HTTPS 协议,但网站身份未验证, 无法保证不被中间人嗅探。
  • 地址为绿色,表示安全且可信任,使用 HTTPS 协议。

HTTPS 的原理是什么,客户端与服务器信息交换的时候到底经历了什么,为什么能保证信息安全?

下面我们由浅入深,逐步揭开 HTTPS 的面纱。考虑到个人知识所限,难免有遗漏或错误之处,如你有发现,欢迎在下面留言指出。

█ 基本通讯

我们先从最简单的信息传递开始,如下图所示,A 要发送一条消息给 B:

52234612

ok 一切正常,B 收到了 A 打的招呼。可以简单的认为这就是 HTTP 协议。

但是如果有一个中间人,截获了 A 的消息,A 发往 B 的 “Hello” 就被中间人知道了。

中间人甚至可以隐藏成一个中继站,“帮助” A、B 传送消息,在 A、B 毫不知情的情况下,偷偷获取 A、B 的所有聊天消息。可见使用明文传输的 HTTP 是不安全的。

234513657000

从安全的角度来讲,B 收不到 A 的消息没关系,大不了再发一次或者更换线路。

重要的是不能让中间人知道 A 给 B 发了什么内容

对称加密通讯

A 和 B 为了防止中间人嗅探到他们的消息内容,前往撒哈拉大沙漠正中央的无人区,商量了一个加密算法,这个加密算法使用了一个密钥 K,密钥 K 只有 A 和 B 知道,世界上其他任何人都不知道,就算巧了别人也在用这个密钥,也不知道 A 和 B 在使用此密钥。

A 使用密钥 K 加密自己的消息,然后发送出去,B 收到消息后用密钥 K 对消息进行解密,即得到正确的消息。B 给 A 发送消息也用同样的方法。

52245634612

这就是对称加密,其中密钥 K 同时用来加密和解密消息。

这里一定要区分开加密算法和密钥,密钥是算法的一个参数,算法是使用密钥加密明文的过程。

只要密钥 K 不告诉其他人,并且加密算法、密钥 K 足够安全(长度够长、包含的字符种类够多等),全世界就只有 A 和 B 能够 “读懂” 他们相互之间的消息。

█ 服务器与客户端

由上面的例子可以发现,A、B 是相互 “认识” 的,他们在通讯之前冒着被渴死的危险,沟通好了他们之间的小秘密。

但是作为一台 WWW 服务器,有 N 个客户端要与服务器进行信息交流,而且服务器和客户端可一点都不认识。那怎么才能让服务器和客户端使用相同的密钥进行加密通讯呢?

思考以下几种方案:

  • 所有的客户端和服务器使用同样的密钥。  这无异于不加密,中间人也有公钥。
  • 客户端把密钥以明文的方式发给服务器。  被中间人截获了怎么办。
  • 客户端用密钥把密钥加密,发给服务器。  服务器没有密钥,解不开密钥加密的密钥。
  • 客户端用公钥把密钥加密,发给服务器。  中间人也有公钥,也能解出密钥。
  • 服务器事先就保存好所有客户端的密钥。  服务器怎么知道哪个密钥是哪个客户端的。
  • 让客户端事先登录一下服务器,服务器就可以在数据库匹配到密钥。首先客户端不登录就拒绝访问吗?其次客户端登录的时候,登录账号密码要不要加密,不加密的话被中间人截获了怎么办,加密的话得先登录,陷入了鸡生蛋蛋生鸡的问题…

通过上面的考虑我们发现,密钥不能在客户端和服务器之间传输,也不能存储在服务器中,但是客户端和浏览器却要同时拥有。

似乎无论如何,中间人总能看到客户端和服务器之间的消息。

实际上,还有一种被称为非对称加密的方式,来解决这个问题的一半

█ 非对称加密通讯

在非对称加密中,有两个密钥,一个是公钥,发放给所有人,一个是私钥,只能一方持有。

从原理上讲,不能从公钥推导出私钥,穷举法来求私钥则由于目前的技术、运算工具和时间的限制而不可能。每个实体的密钥总是成对出现,即一个公钥必定对应一个私钥。

使用公钥加密的内容,只有私钥能解开;私钥加密的内容,只有对应的公钥能解开。

加密解密使用了不同的密钥,所以被称为非对称加密。

如下图所示,服务器有一对密钥:公钥和私钥,公钥用来加密信息,私钥用来解密信息:

50002245634612

客户端向服务器打招呼,不包含敏感信息,被中间人嗅探到了没关系。服务器收到招呼后,把公钥发给客户端,客户端用公钥把信息加密再发给服务器,服务器用私钥进行解密。

由于中间人没有私钥,就算拿到了公钥,也解不开客户端发往服务器的信息。现在至少客户端向服务器这个方向的数据是安全的。这就是上面说的 “解决了一半”。

我们再想一步,既然客户端能把信息安全地发给服务器,密钥也是信息,客户端可以把密钥发给服务器呀!这样一来服务器和客户端就同时拥有了一个别人不知道的密钥!接下来就可以使用对称加密的方式,实现双向安全通讯了!

实际上,现实中的客户端和服务器正是通过这样的方式,使得信息传输进一步安全。

为了让密钥更加难以被破解,以及不同客户端之间的密钥各不相同,客户端和服务器使用随机数确定密钥,如下图所示:

190661334484050

图中 number1、number2、number3 ,依次由客户端、服务器、客户端随机生成,并且通过非对称加密的方式发送给对方,用于生成对称加密用的密钥。

中间人可以嗅探到 number1、number2,和加密过的 number3,但是无法解密出 number3,也就无法知道我们最终所使用的加解密密钥!

这就是为什么 HTTPS 握手阶段有好几个随机数。

█ 狡猾的中间人

到了这里,我们似乎达到了双向安全通讯的目标,“物理学的大厦” 似乎已经落成。

然而事情并没有这么简单,且听题:

如果中间人截获了线路,站在线路中间,用自己的公钥替换服务器的公钥,然后用自己的私钥解密客户端的 number3,就能得到对称加密密钥!有了对称加密密钥就能伪装在中间当 “中继站” 。

如果说我们先用不对称加密法加密公钥,那就又陷入了鸡生蛋蛋生鸡的泥潭之中….

解决这个问题的关键在于:客户端如何判断接收到的公钥没有被替换

只有确定收到的公钥是服务器发过来的,这个公钥才可用于下一步的加密,否则加密被破解,非对称加密失效。这就是密码学中的身份验证问题。

如何进行身份验证,找个双方都信任的公证人公证一下可以吧。当然可以,即下面要说的 CA 认证机构

█ 应运而生的 CA 认证机构

如下图所示,有一个权威的认证机构(Certificate Authority),权威到什么程度,权威到各大浏览器都预置了他们的 CA 根证书。微软信任他们,谷歌信任他们,其他大公司也信任他们,共同维护监督这个机构。

服务器向 CA 机构提交信息,申请证书。 CA 机构对申请人的信息进行审查,越高级的 CA 证书审查越严格,确保证书发放给了服务器和域名的实际拥有者。

CA 机构审核通过后,开始制作证书。主要流程有:1,用 Hash 算法对证书信息生成一个数字摘要;2,用私钥加密数字摘要,生成一个数字签名;

证书制作完成后,CA 机构将证书和对应的私钥颁发给服务器,服务器安装证书,接下来就可以进行通讯了:

ca2425124351246

通讯流程和上面讲的一样,这里就不赘述了。

重点看客户端如何验证服务器公钥,而服务器公钥存在于服务器发给客户端的证书中。

只要证明以下两点,就能说明服务器公钥是可信的:

  • 证书确实是由对应的 CA 机构颁发的(证书没有被中间人替换)
  • 证书内容没有被篡改(证书内容没有被中间人篡改,即服务器公钥可信)

如何证明呢?

客户端拿到证书后,对证书的验证步骤如下:

yzca24251243234251246

1,使用客户端预置的 ca 根证书里的 ca 公钥,解密数字签名,得到数字摘要。(非对称加密的解密,如果解的开,就说明该证书是由 ca 机构签发的)

2,对数字摘要使用 Hash 算法,得到 Hash 值。

3,对证书中的服务器公钥使用 Hash 算法,得到 Hash 值,与第二步的值进行对比。相同即说明证书内容没有被篡改,公钥没有被替换。

如果中间人替换了服务器发给客户端的证书,由于非对称加密,客户端无法使用对应公钥解开证书数字签名,可判证书无效。如果中间人篡改了证书里的服务器公钥,由数字摘要 Hash 出的值则与明文公钥 Hash 出来的值不同,可判证书无效。中间人一脸懵逼  (⊙ˍ⊙)

通过上面的验证步骤可以看到,客户端验证证书时候,使用的 ca 公钥是客户端预先内置的。为什么要预先内置呢?因为如果需要的时候再传输,首先效率低,其次又会陷入鸡生蛋蛋生鸡的泥潭之中。

为什么服务器的公钥不预先内置呢?这个上面说过,世界上服务器无数,客户端根本维护不过来,而 ca 机构就那么几个。可以打开浏览器的设置页面,一般在 “安全” 选项中,可以找到服务器证书以及 ca 根证书。

█ 并非绝对安全

为了和中间人斗智斗勇,网络工程师们也是费劲心思。

想象一下,如果有个中间人打入 ca 机构内部,以某服务器为目标,把包含其公钥的证书签发给中间人,中间人就可以翻过刀山(非对称加密验证),跨过火海(Hash值验证),窃取用户信息。

或者打入客户端内部,修改 ca 机构的公钥,客户端就会把中间人当成 ca 机构,比没有 ca 机构更加严重,这个时候客户端拿到的 “可信证书”,百分百是不可信的。

所以这样的结构并非绝对安全。

但是这样的结构,足以抵挡 99% 的中间人,非常大程度的增加了中间人窃听的难度。

60% 由 ca 机构负责,所以为什么 ca 机构要权威,世界上各国商业与政府官方都信任他,并且监督他。

30% 由操作系统、浏览器等客户端负责,要尽量少 bug ,及时修复漏洞,不能被中间人钻空子。

9% 由用户自身负责,提高安全意识,谨慎使用网络代理,使用正版软件,识别真假网站,预防病毒,安全操作。

还有 1% 无法抵挡,不可控,比如社工之类的,都概括为意料之外吧。

*以上比例仅为个人观念,并非权威数据。

█ 回归正题

说了这么多好像一句都没有 HTTPS,现在我们来切入一下标题。

HTTP 协议,就相当于上面说的基本通讯。(TCP 连接建立后,发起 HTTP 请求,数据以明文的形式传输)

HTTPS 协议,就是最终加密方案,相当于 HTTP + SSL ,所以称为 HTTPS 。(TCP 连接建立后,SSL 执行身份验证、协商密钥、加密等工作,HTTP 进行传输)

正是通过这样的方式,服务器和客户端实现了安全的通讯。

█ 拓展

从此 A 和 B 使用 HTTPS 进行通讯,A 当客户端,B 当服务器,再也不用冒着被渴死的风险,去撒哈拉大沙漠中心的无人区商量密钥了。

但是有一天他们俩吵架了,B 想 “凭什么只准他怀疑我,不准我怀疑他,他能确定我是我,那我怎么确定他是他”

这要怎么办?

答案是有的,就不说了,请读者自行思考吧。文中如有错误,请留言指出,谢谢!

发表评论

Powered by WordPress | Theme Revised from Doo

苏ICP备18047621号

Copyright © 2017-2023 追光者博客