HTTPS是如何保证连接安全:每位Web开发者都应知道的

“HTTPS协议的工作原理是什么?”这是我在数天前工作项目中需要解决的问题。

作为一名Web开发者,我当然知道 HTTPS 协议是保障用户敏感数据的好办法,但并不知道这种协议的内在工作机制。

它怎么保护数据?有人监听线路的情况下,服务器与客户端之间如何建立安全的连接?安全证书又是什么,为什么还要花钱买呢?

 

一系列通道

在深入讲解原理细节之前,让我们首先简单了解下HTTPS所防范的的问题,以及安全连接为何如此重要吧。

在你访问自己喜欢的站点时,从你的电脑发送的请求会在各个不同的网络之间传递——这些网络很有可能是用来偷听,甚至篡改你的信息。

HTTPS是如何保证连接安全

 

局域网中,信息从你的电脑传输到其他电脑,传输到接入点,到ISP的路由器、交换机,最后到达骨干网线路。这样的一个过程中,有许多不同的组织在传送着你的请求。这时,如果不怀好意的用户侵入这条线路之中的任何一个系统中时,他们将很有可能看到线路中传送的内容。

而一般情况下,Web请求和相应都经由普通的HTTP协议明文传送。HTTP协议默认不使用加密协议,都是由于这些原因:

  • 加密消耗了很多计算资源。
  • 加密占用了更多的传输带宽。
  • 加密后缓存机制会失效。

不过,Web开发者会时不时遇到在连接中传送密码、信用卡号等敏感信息的情况。所以,有必要为这些页面做好防嗅探的准备措施。

 

传输层安全协议(TLS)

虽然下面讲解的内容和密码学有关,但是这里只是一个简单的介绍,不熟悉相关知识也应该看得懂。在实践中,是密码学算法确保了通信过程的安全,同时也抵御了潜在的信息黑手——干扰通信和监听的人。

SSL协议的继任者——TLS协议,常被用来实现安全HTTP连接(HTTPS)协议。在OSI网络模型中,TLS协议比HTTP协议的工作更加底层。确切来说,就是TLS的那部分连接发生在HTTP的连接之前。

TLS是一种混合的加密机制。它具有多种范式,接下来所看到的是对于这两种范式(用于共享秘密信息和身份认证(确保声称的身份和实际身份一致)的公钥算法和用于加密请求与回应机密信息的对称式算法)的说明:

公钥加密机制

使用公钥加密机制,双方各自拥有一份公钥和一份私钥,公钥和私钥通过数学演算联系在一起。公钥用于将明文转化为密文(变成了一堆乱码),私钥用来解密这一堆乱码般的信息。

一旦信息被公钥加密,它将只能由相应的私钥解密。两者缺一不可,而且也不能反过来使用。公钥可以自由传播,无需担心系统安全性降低;但私钥应妥善保管,不可将其泄露给未经授权解密的信息的用户,这就是公钥和私钥这两个名称的由来。

公钥机制相当酷的地方在于,通信双方可以在最初不安全的通道上建立起安全可靠的通信连接。

客户端和服务器都可以使用各自的私钥,只要共享了一部分公开信息,也就是共用了同一个公钥的情况下,就可以建立起相应的会话。

这意味着即使有人坐在客户端或者服务器前查看连接过程,他们也不会知道客户端或者服务的的私钥,也不会知道会话所共享的密码。

这得靠什么实现?靠数学!

Diffie-Hellman

这种密钥交换最常使用是Diffie-Hellman的密钥交换法。这项过程允许服务器和客户端双方商定共同的保密信息,而不需要在传输过程中交换这个信息。这样一来,即使嗅探者查看每个数据包,也不能确定连接上传输的共享密码是什么。

在最初的DH式密钥交换发生之后所生成的共享信息,可以在会话接下来的通信中使用更简洁的对称式加密法,我们之后就会看到对称式加密法的说明。

一点点数学

公钥算法的特点就是很容易由算子计算出结果,而基本上不可能作逆向运算。这也就是使用了两个质数的所要达到的目的。

现在假设Alice和Bob分别是参与DH式密钥交换过程的两方,他们一开始会商议确定一个小质数(一般是2,3,5这样的小数字)和一个大质数(有300位以上)作为加密的原始信息。小质数和大质数都可以直接传输,不必担心交换过程中的不安全。

需要明白的是,Alice和Bob各自都持有着自己的私钥(100多位的数),而且也永远不应该共享自己的私钥。不光是两人之间,也包括其他不相关的人都不应该拥有这两组私钥。网络中传输的是他们的私钥、小质数和大质数混合运算得到的结果。更确切来说,就是:

  • Alice的结果 = (小质数Alice的密码)% 大质数
  • Bob的结果 = (小质数Bob的密码)% 大质数
  • (“%” 符号表示取模运算,即取得除法运算的余数)

所以Alice使用大质数和小质数加上自己的私钥运算,就会得出结果,而Bob做同样的计算,也能得到相同的结果。当他们接收到对方的运算结果时,他们可以由数学计算导出会话中所要传输的信息,也就是说:

Alice计算的是

  • (Bob的结果Alice的密码)% 大质数

而Bob则计算

  • (Alice的结果Bob的密码)% 大质数

Alice和Bob得出来的数字相同,这个数字也就是会话中所要共享的密码。请注意,双方都没有向对方传输各自的私钥,而连接过程中也没有明文传递保密信息。这一点真是太棒了!

对数学不好的人而言,维基百科上有一张混合颜料的图可以用来说明情况:

Alice和Bob

请注意图中一开始的颜色(黄色)最后都会有Alice和Bob的颜色参与计算。这就是双方会得到同样结果的原因。对于观看中间过程的人来说,唯一在连接中发送的半合成信息是毫无意义的。

对称式加密机制

每次会话中只需要产生一次公钥交换的过程。在接受了同一个共享保密信息以后,服务器和客户端之间会使用更为高效的对称式加密机制进行通信,省去了来回交换的额外花销。

在接受了之前的共享保密信息之后,还会使用一套密码机制(一般是一组加密算法),使用共享的密码安全地通信,加密解密各自的信息。而窃听者只会看到一堆乱码在传来传去。

身份认证

DH式密钥交换允许双方创建私有的,共有的密码,但通信双方怎么确保是真正想要对话的人呢?这里就涉及到了身份认证的问题。

假设我拿起电话,跟我的朋友进行DH式密钥交换,在电话已经被干扰的情况,实际上是在跟其他人交换信息。在使用共享密码了以后,我仍然可以安全地与“朋友”交换信息,没有人可以解密我们的通信信息,但是“朋友”并不真的是我的朋友,这可是十分不安全的!

要解决身份认证问题,需要有配套的公钥基本设施,来核实用户的真实身份。这些设施用来创建,管理,发布,收回数字证书。而数字证书正是你需要为站点使用HTTPS协议付费的恼人事项。

但是,什么是数字证书,数字证书又是如何保证信息更加安全的呢?

证书

从更高的层次来讲,数字证书是将机器上的公钥和身份信息绑在一起的数字签名。数字签名担保某份公钥属于某个特定的组织和机构。

证书将域名(身份信息)和特定公钥关联起来。这就避免了窃听者将自己的服务器伪装成用户将要连接的服务器,并进行攻击的行为。

在上面打电话的例子中,攻击者可以尝试展示自己的公钥,装作是你的“朋友”,但是证书上面的签名信息便显示出:这份证书不是来自我信任的人的。

要受到一般浏览器的信任,证书本身还应当受到CA的信任。CA公司对认证会进行人工核查,确定申请主体满足以下两个条件:

  1.  在公共记录中存在着这个人/这家公司。
  2. 需要签名的证书上标明的域名的确由申请主体实际控制。

当CA查证,得出申请人属实,并且的确拥有这个域名的结果,CA便会为证书颁发签证,盖上“已核准”的戳记,表明网站的公钥属于这个网站,而且可以信任。

你的浏览器中会内置一系列受信任的CA列表。如果服务器返回的是未经过受信任CA签证的证书,浏览器会弹出大大的警告,这就在系统中多了一层安全措施,如果不然,任何人都可以四处签售伪造的证书。

证书

这样一来,即使攻击者将自己的公钥拿出来,生成这份密钥,声称自己的伪造服务器就是“facebook.com”,浏览器也会因为检查到“未经受信任CA签名的证书”而弹出提示。

一些关于证书的其他事项

增强式认证

在常规的X.509 证书之外,增强式认证证书提供了更强力的认证。

要授予增强式认证证书,CA会对域名持有着做更加深入的查验(通常需要提供护照和水电费账单等信息)。

这种类型的证书,浏览器中大锁图标的显示位置背景也会变成绿色。

在同一台服务器上运行的多个网站

在HTTP协议连接开始之前进行的TLS协议握手流程,很有可能存在着多个网站存放在同一个服务器,使用相同IP地址的情况。

虚拟主机的Web路由是由Web服务器分发,但是TCP握手的过程,却是发生在连接之前。整个系统的单张证书会被发送到服务器的所有请求之中,这种流程会在共享主机的环境中发生问题。

如果你正在使用Web主机上提供的服务,他们会在你使用HTTPS协议之前要求使用独立的IP地址。不然主体提供商就需要每次在服务器上有新站点的时候,取得新证书(并且向CA重新申请认证)。