谈谈HTTPS!

从咕果谈起

就在不久之前,咕果宣布 Chrome 将在不久之后提前移除对于 HTTPS 网站的“安全”标识,同时对于 HTTP 网站强制显示“不安全”。虽然咕果表示目前 HTTPS 的普及已经达到他们认为足够的地步了,但是我看着国内的进展…啧。

为什么要使用 HTTPS?HTTPS 提供的不只是加密功能。事实上,许多 Web 新技术,如 HTTP/2,Service Worker 等都需要依托 HTTPS 才能实现,相信这也会成为未来的趋势。

什么是 SSL?

从网络模型来看,SSL 在 HTTP 应用层之下,TCP 传输层之上提供了一层传输安全层,确保了经过传输层的数据都是经过加密的。

谈谈HTTPS!

SSL 作为 HTTPS 的基础最早由网景于 1994 年提出。虽然 HTTP 协议本身提供了基本认证和摘要认证(后来提出)两种客户端认证方案,但是毕竟除了用户名和密码外的所有数据仍然是明文传输的(甚至基本认证只对密码信息做了 Base64 编码),要保证传输的安全性还得依靠 SSL。SSL 本身是一种二进制协议,避免了随随便便一个代理就能读取/修改数据的问题。

随着技术发展,SSL 本身也在不断改进。从 SSL 1.0、SSL 2.0 到 SSL 3.0,再到标准化后的 TLS(目前 TLS 1.3 刚刚定稿),这个协议本身也在完善当中。在本文中,我们按照一般惯例使用 SSL 一词同时指代 SSL 和 TLS 两种协议。

翻开历史书

加密方法离不开数学基础,为了更好地解释加密原理,我们先来了解一下加密的基础知识。当然,如果已经了解了就直接跳过吧。

人类使用加密已经有几千年的历史了。最初,人们使用特定的方法处理文本使其在被截获之后也不会泄露信息。我们通常把这种特定的方法叫做密码。传说凯撒曾使用过一种三位位移密码,也就是将文本中的所有字母替换为这个字母在字母表中后三位的字母。这种方法是一种密码。也就是说,密码 C 接受明文 R 一个参数,输出密文 E。

谈谈HTTPS!

然而,使用单一密码的加密非常容易被破译,而且一旦被破译,以往和未来的所有密文也不再安全。为了解决这个问题,人们提出了新的方法也就是密钥。用同一种密码加密,输入不同的密钥就会产生不同的结果。比如上文中的三位位移密码,如果把 3 当做密钥,那么不同的密钥(1,2,3,4,5…)就会产生不同的输出。这种时候,就算密码被破译,只要密钥的可能值足够多,要得到明文还是相当困难的。也就是,密码 C 现在接受明文 R 和密钥 K 两个参数,产生密文 E。不同的 R 和 K 组合会产生不同的 E。

谈谈HTTPS!

然而这种方法仍然有问题。密文的接收方要解密得到明文,必须要得知密码和密钥两个信息。通常密码和密钥组合是变化的(不然就和没有密钥一样了),要正确解密,发送方和接收方每次都必须要交换密码和密钥信息,通常是只交换密钥而密码不变。但密钥存在被截获的可能,要确保安全必须对密钥进行加密,然后加密密钥也需要交换密钥,然后第二个密钥也需要加密…很快这就变成了一个鸡生蛋问题,很明显是不可能实现的。

谈谈HTTPS!

到目前为止,我们讨论的都是对称加密,也就是加密和解密用的是相同的密码和密钥。对于无限加密的问题,使用对称加密是无解了。此时,我们的救星非对称加密就登场了。

非对称加密可以使用不同的密钥来分别加密和解密文本,它们通常是配对的,我们叫它们公钥和私钥。使用相同的密码时,接受方只需生成一对公钥和私钥,然后保管好自己的私钥并公开公钥。发送方只需要用商定的密码和接收方的公钥作为密钥来加密文本即可。加密后的文本只有使用私钥才能解开,公钥本身是无法解开的。也就是说,密码 C 对于明文 R 和公钥 PK 产生的输出只能由与密码 C 对应的解码 D 和公钥 PK 对应的私钥 SK 才能解密回明文。

谈谈HTTPS!

这里就不详述数学上的证明了,有兴趣的可以自行了解。

通过这种方式,接收方可以保证密文只能由接受方进行解码,交换公钥并不会破坏加密的安全性。更棒的是,私钥和公钥是可以互换的,即是,使用公钥 PK 加密并使用私钥 SK 解密得到的结果和使用私钥 SK 加密并使用公钥 PK 解密得到的结果是一致的,都是原始明文。

这样的话,我们甚至可以使用非对称加密验证接收方的身份。毕竟只有接收方拥有私钥,可以要求接收方用私钥加密明文并试图用其公钥解密来确保对方就是拥有正确私钥的那一方。如此看来,有了非对称加密,似乎一切都完美了。

等等!

你可能会发现一些问题。如果有一个聪明的中间人(或者说网络中的某一台代理),他可能可以轻松破解非对称加密。

对的!试想以下的场景: A 和 B 作为两位优秀的魔法少女常常需要互通信件,然而不巧邪恶的 E 同学总是试图偷看 A 和 B 的对话,于是 A 和 B 决定使用非对称加密来加密信件以解决问题。

然而 E 同学想出了一个办法。A 向 B 发送信件时,B 会先向 A 发送她的公钥以便 A 加密文本,这时 E 将其截获,记下 B 的公钥然后自己生成一套公钥和私钥并将自己的公钥伪装成 B 的信件重新发送给 A。不知情的 A 会用 E 的公钥加密文本并发回给 B。E 可以再次截获信件,此时他利用自己的私钥便可以轻松读取信中的内容了。然后 E 将信件重新使用 B 的公钥加密并发送给 B,这样 B 也不会发现异常,认为自己成功与 A 完成了一次沟通,殊不知 E 已经读取到了信的内容。当 B 要向 A 寄信时,E 可以如法炮制读取 A 和 B 的对话。

怎么办才能避免 E 读取内容呢?幸好,我们有一种方法可以在 E 偷偷摸摸更换密钥时就发现问题并及时停止。要使用这种方法,我们需要有请我们的下一位选手登场。

欢迎,公正的第三方

现在,作为第三方的 C 登场了。他会作为一个验证人帮助信件的接收方验证收到的信件有没有经过篡改以及是不是真的由 B 发出的。

整个过程这样进行。C 先生成一对公私钥,然后将公钥亲自告诉 A 和 B。A 发信给 B 时,C 会提前把 B 的公钥和一些 B 和 C 的基本信息放在一起,然后用自己的私钥加密这段信息并将密文交给 B。B 随后只需将这段密文交给 A 即可。A 随后会试着使用 C 的公钥解开密文,如果成功了,那就说明信件没有经过篡改,并且 A 也安全地获得了 B 的公钥。如果失败了,就说明有人篡改了这段密文,信件即作废。当 B 给 A 寄信时将整个过程反过来即可。看,这样我们就可以安全的交换密钥而不用担心内容被窃听了。可怜的 E 现在束手无策。

说好的 HTTPS 去哪了?

别激动,其实 A、B、C、E 的故事就是一次典型的 HTTPS 连接。

慢慢来,实际情况会比上面的故事稍稍复杂一些。我们把 A 看作客户端,通常情况下也就是浏览器,B 看作服务器,E 看作网络链路上某台邪恶的代理,C 是一位公正的第三方,顺便,我们把 C 交给 B 的那段含有一些基本信息和 B 的公钥的密文叫做数字证书。现在,我们可以把 C 叫做证书颁发机构。

在真实情况下,数字证书会包含一些加密的基本信息。毕竟数字证书并没有统一的标准,这些加密信息会用来告诉 A 如何解密数字证书。当然这些信息不会被加密,不然 A 完全无法解密数字证书。因此现实情况下,C 会对数字证书包含的所有内容建立一个摘要(你可以把它当做简介),然后只对这个摘要用自己的私钥进行加密。这个过程叫做签名。当 A 收到证书后,会解密这段摘要,然后自己通过相同的算法独立算出证书的摘要——如果是一样的,那就没问题了。

那么现在开始连接。A 向 B 发出了一个请求。在建立连接后,B 会将数字证书发送给 A。A 会验证数字证书(甚至会询问 C 确保这张证书没有作废)。如果成功,A 会利用从证书中取得的 B 的公钥在加密环境下协商出一个一致的临时密钥,接下来双方会用这个密钥进行对称加密来互相交流。

原创文章,作者:Harem,如若转载,请注明出处:https://www.hgjun.cn/?p=79

发表评论

电子邮件地址不会被公开。 必填项已用*标注

联系我们

QQ-501439094

撩一撩:点击这里给我发消息

邮件:501439094@qq.com

工作时间:周一至周五,9:30-18:30,节假日休息

隐藏