原文: http://heckpsi.com/archives/986
这篇短文对HTTPS的介绍非常容易理解, 推荐对https不了解的同学阅读, 作为入门材料
每当我们讨论到信息安全的时候,我们最长接触到的信息加密传输的方式莫过于 HTTPS 了,当我们浏览器地址栏闪现出绿色时,就代表着这个网站支持 HTTPS 的加密信息传输方式,并且你与它的连接确实被加密了。但是 HTTPS 并不是一个单一的东西,它知识我们常见的 HTTP 协议和某个加密协议的一个混合,这个加密协议通常会是 TLS。那么 HTTPS 为什么安全呢?其实我们需要先考虑 HTTP 为什么不安全。
假设你坐在一个教室里,你现在非常想把某个信息传递给教室里的另一个人,一般来说,会选择,传纸条。传纸条这个比喻其实非常正确,这就是互联网的一个基础协议 TCP/IP 协议基本的工作模式。而通常,HTTP 协议的数据是使用 TCP/IP 协议进行发送的。HTTP 指的是你在纸条上写明你要传送的目的地是哪个同学的坐位,然后再是要传递的内容。途径的同学拿到纸条后根据纸条上显示的地址依次传过去就好了。这样要面临的第一个问题就是:途径的同学可以完全知道你写了什么。
这就是 HTTP 面临的第一个问题,这个问题通常被叫做 “窃听” 或者 “嗅探” ,指的是和你在同一个网络下或者是途径的路由上的攻击者可以偷窥到你传输的内容。这是 HTTPS 要解决的第一个问题。这种问题通常是通过“加密”来解决的。从非常原始的角度来考虑,其实就是双方约定一个暗号。用什么字母去替代什么字母之类的。不过考虑到互联网每天有无数信息需要加密,这种原始的加密方法似乎不太适合。不过实际上方法也差不多,一般是采用一种叫做 AES 的算法来解决的。这种算法需要一个 密钥 key 来加密整个信息,加密和解密所需要使用的 key 是一样的,所以这种加密一般也被称为“对称加密”。AES 在数学上保证了,只要你使用的 key 足够足够足够足够的长,破解是几乎不可能的。
我们先假设这种破解确实是不可能的,而且目前也确实没有对 AES 本身能发动起有效的攻击的案例出现。
我们再回到这个教室,你接着要传小纸条,你把地址写上后,把要传输的内容用 AES 蹭蹭蹭加密了起来。刚准备传,问题来了。AES 不是有一个 key 吗?key 怎么给目的地啊?如果我把密钥直接写在纸条上,那么中间的人不依然可以解密吗?在现实中你可以通过一些其它方法来把密钥安全传输给目的地而不被其他人看见,但是在互联网上,要想这么做难度就很大了,毕竟传输终究要经过这些路由,所以要做加密,还得找一个更复杂的数学方法。
于是聪明的人们发明了一种更复杂的加密算法——非对称加密。这种加密或许理解起来比较困难,这种加密指的是可以生成一对密钥 (k1, k2)。凡是 k1 加密的数据,k1 自身不能解密,而需要 k2 才能解密;凡是 k2 加密的数据,k2 不能解密,需要 k1 才能解密。这种算法事实上有很多,常用的是 RSA,其基于的数学原理是两个大素数的乘积很容易算,而拿到这个乘积去算出是哪两个素数相乘就很复杂了。好在以目前的技术,分解大数的素因数确实比较困难,尤其是当这个大数足够大的时候(通常使用2的10次方个二进制位这么大),就算是超级计算机解密也需要非常长的时间。
现在利用这种非对称加密的方法,我们来设想一个场景。你继续想要传纸条,但是传纸条之前你先准备把接下来通讯的对称加密密钥给传输过去。于是你用 RSA 技术生成了一对 k1、k2,你把 k1 用明文发送了出去,路经有人或许会截取,但是没有用,k1 加密的数据需要用 k2 才能解密。而此时,k2 在你自己的手里。k1 送达目的地后,目的地的人会去准备一个接下来用于对称加密传输的密钥 key,然后用收到的 k1 把 key 加密了,把加密好的数据传回来。路上的人就算截取到了,也解密不出 key。等到了你自己手上,你用手上的 k2 把用 k1 加密的 key 解出来,现在全教室就只有你和你的目的地拥有 key,你们就可以用 AES 算法进行对称加密的传输啦!这时候你和目的地的通讯将无法再被任何人窃听!
当然,这时候你可能会问两个问题。
既然 非对称加密 可以那么安全,为什么我们不直接用它来加密信息,而是去加密 对称加密 的密钥呢?
这是因为 非对称加密 的密码对生成和加密的消耗时间比较长,为了节省双方的计算时间,通常只用它来交换密钥,而非直接用来传输数据。
使用 非对称加密 是完全安全的吗?
听起来确实是挺安全的,但实际上,还有一种更恶劣的攻击是这种方法无法防范的,这就是传说中的“中间人攻击”。我们继续让你坐在教室里传小纸条。现在你和目的地上途径一个中间人,他有意想要知道你们的消息。由于这个描述比较复杂,我们将你称为 A,你的目的地称为 B,而中间人称为 M。当你要和 B 完成第一次密钥交换的时候,途径了 M。M 知道你要进行密钥交换了,它把小纸条扣了下来,假装自己是 B,伪造了一个 key ,然后用你发来的 k1 加密了 key 发还给你,你以为你和 B 完成了密钥交换,实际上你是和 M 完成了密钥交换。同时 M 和 B 完成一次密钥交换,让 B 误以为和你完成了密钥交换。现在,由 A -> B完整的加密,变成了 A(加密连接1) -> M(明文)->B(加密连接2)的情况了。这时候 M 依然可以知道 A 和 B 传输中的全部信息。
对于这种事,我们似乎很难找到一个解决方法来解决这个问题,除非我们能从源头保证,你密钥交换的对象是安全的。这时候我们就要认识互联网 HTTPS 和你传纸条的微妙区别了。你传纸条时,你和你的目的地的关系几乎是对等的。而你访问网站时,你访问的对象通常是一个比较大的服务供应商,他们有充沛的资源,也许可以证明他们的合法性。
这时候我们会引入一个第三方叫做 CA。CA 是一些非常权威的专门用于认证一个网站合法性的组织。服务商可以向他们申请一个证书,使得他们建立安全连接时可以带上 CA 的签名。而 CA 的安全性由操作系统或浏览器来认证。你的 Windows、Mac、Linux、Chrome、Safari 等会在安装时带上一个他们认为安全的 CA 证书列表。如果和你建立安全连接的人带着这些人的签名,那么认为这个安全连接是安全的,没有遭到中间人攻击。
CA 证书通常情况下是安全的。因为一旦某个 CA 颁发出的某个证书被用于了非法用途,浏览器和操作系统一般会通过更新将整个 CA 颁发过的全部证书全部视为不安全。这使得 CA 通常在颁发证书时是比较小心的。
所以通过 对称加密 + 非对称加密 + CA认证 这三个技术混合在一起,才使得 HTTP 的后面加上了一个 S —— Security。实际上 HTTPS 的协议比我这里描述的更复杂一些,我这里说的主要是基本的实现原理。因为其中任何一环稍有闪失,就会使得整个加密都将变得不安全。这也是为什么 HTTPS 的加密协议从SSL 1.0 升级到 SSL 3.0 再被 TLS 1.0 现在被 TLS 1.2 取代,其背后都是一环环细节上的修改,以防任何地方的闪失。
但即使如此,你的 HTTPS 尽可能的保证了你传输的安全,但这种安全也不是绝对的。比如 CA 证书出了问题被用于了中间人攻击,在短期内,你的安全将会陷入直接的麻烦直到浏览器或操作系统重新更新了你的 CA 列表或者你手动调整了这个列表。但大多情况下不必杞人忧天,它基本上是安全的。
当然了,路由也可以选择直接丢包,它看不到的,也不让你看到。