科普-HTTPS背后的那些事儿

96
阿尔法二狗
0.1 2017.06.08 23:46* 字数 2511

首先为什么要用HTTPS协议,当然是为了安全啦,所有通过HTTPS协议传输的数据都是经过加密的,即便黑客在网络层抓取了数据包也是无法获得你数据包中的内容的。所以通过HTTPS协议传输的数据是非常安全的。这一点大部分人都知道,但是下面这几个问题你可能不知道:

  • HTTPS是怎么加密你的数据的?
  • 为什么通过浏览器浏览访问一些HTTPS协议的链接的时候会有安全告警?
  • HTTPS证书是怎么回事?

如果你能很好的回答上面的问题说明你已经很了解HTTPS的工作原理,出门右转不送。如果不能,好好往下看。

先纠正一点,其实根本就没有HTTPS这个协议, HTTPS实际是应用层的HTTP协议+SSL/TSL协议构成的一个工作流程。在你访问443端口的时候,浏览器不直接将HTTP协议需要传输的数据发送给传输层,而是经由SSL/TSL加密后,嗯。。。。其实说SSL/TSL是HTTP协议的杜蕾斯还是蛮形象的

image.png

为了初步了解HTTP+SSL/TSL的工作过程,需要先了解几个基本概念

  • 密钥
    通常加密算法将要传输的内容和一个随机字串一起加密成密文,当解密的时候必须要同时知道解密算法和相应随机字串才可以将密文还原成原始内容。这个随机字串就称之为密钥
  • 对称加密算法
    加密和解密的时候使用相同密钥的加密算法
  • 非对称加密算法
    加密和解密的时候使用不同密钥的加密算法,大名鼎鼎的RSA...
  • 公钥+私钥机制
    公钥+私钥的机制,实际就是基于非对称加密算法的,你要传输的协议用公钥加密,然后服务器用私钥解密密文到原始数据。看过一个比喻蛮形象的,公钥就像是锁头,私钥就像是钥匙。你用锁头锁住了数据,如果没有钥匙是打不开的。但是这一比喻并不100%准确。因为公钥不光是用来加密数据,私钥也不光是用来解密数据的,在公钥+私钥体制中,私钥也可以用来加密数据,而公钥可以用来解开私钥加密的数据 (即私钥为锁头,公钥为钥匙)
  • SSL证书
    SSL证书被安装在服务器端,由2个证书组成,公共证书(会被发送给客户端)和私有证书(仅服务器拥有),听名字也猜到一个和公钥有关一个和私钥有关。但实际上没那么简单,不过目前可以暂时这样理解。

基本概念了解之后就可以来尝试回答问题1

HTTPS是怎么加密你的数据的?

1 浏览器访问https://<some domain>
2 服务器找到安装的SSL证书并且将公共证书发送给浏览器
3 浏览器验证证书是否有效,如果有效则继续往下进行
4 浏览器生成一个随机字串(密钥)并且用接收到的公共证书中的公钥来加密这个随机字串,然后将加密过之后的随机字串发送给服务器
5 服务器接收到密文然后用私钥(钥匙)来解密由公钥(锁头)加密的随机字串并告知浏览器自己已经得到密钥
6 浏览器用之前生成的随机字串(密钥)以对称加密算法来加密要传输的数据并发送给服务器
7 服务器接收到加密后的数据并通过之前得到的随机字串(密钥)来解密数据
8 服务器用随机字串以对称加密算法来加密response的数据并返回给浏览器
9 浏览器用随机字串解密response的数据然后显示

在整个过程中黑客即使捕获了你的数据包,也是无法获得数据的内容,因为黑客没有私钥,就没法解密获得公钥加密的随机字串(密钥),没有密钥就无法解密由密钥加密的数据内容,Cool....But....有个漏洞,如果在第一步的时候黑客拦截到了浏览器的请求,然后伪造服务器返回假的公共证书,或者拦截到服务器返回的真实证书并且修改证书中的公钥,那么黑客不是可以通过自己的私钥来解密数据了吗?幸好,有第三步: 浏览器对公共证书的验证。当浏览器对于公共证书验证失败的时候,则会视为证书无效,也就会报一个HTTPS未知证书的警告去提醒用户。现在你知道问题2的答案了吗?

为什么通过浏览器浏览访问一些HTTPS协议的链接的时候会有安全告警?

所以,即便黑客篡改了证书,则证书一定是一个无效的证书,用户就能够收到告警去避免悲剧发生。如果你要是无视这个警告,OK,我只能说no zuo no die why you try.

当然,证书无效并不一定是因为黑客篡改证书所致,还有可能证书过期,或者服务器使用的证书并不是通过证书提供商发布的都会导致证书验证失败。

所以,浏览器到底是怎么验证证书的?好吧,我试着来回答一下问题3

HTTPS证书是怎么回事?

要进一步了解这个问题需要再介绍几个概念(神烦,好多概念>_<)

  • 签名算法
    签名算法是一种不可逆的用来获得被传输内容hash值的hash算法。
  • 数字签名
    用签名算法获取到的被传输数据的hash值就是数字签名。数字签名用来供客户端验证被传输的数据是否被更改过(被修改的数据的hash值一定和原数据的hash值不同)。数字签名将和数据本体一起被传输给客户端,然后客户端用相同的签名算法得到数据本体的hash值,然后和数字签名比对,如果相同说明数据没有被修改过,反之说明数据已经被修改了。
  • 证书颁发者
 发布/颁发数字证书的机构,通常是一些被信任且信誉良好的机构,如SecureTrust CA,赛门铁克等
  • 证书数据库
    一般来讲这个数据库由操作系统和浏览器提供,你的OS/浏览器一般会预装了很多数字证书,这些证书都是由各大证书颁发者所拥有。

这几个概念明了了,接下来看一下,数字证书的组成(只说公共证书了,因为比较重要而且私有证书内容大同小异):

  • 证书颁发者
  • 证书拥有者
  • 证书有效期
  • 域名
  • 公钥
  • 数字签名和签名算法
  • 数字签名和签名算法的加密算法
    其他几个组成部分都比较好理解,最后一个绕口的数字签名和签名算法的加密算法是什么鬼? 刚才说了,数字签名和签名算法是用来供客户端验证被传输内容是否被更改来的,那么如果黑客修改了数据本体的同时修改了数字签名那么客户端不就会以为数据没有被更改过了吗?所以数字证书的签名和签名算法都是被加密过的,而这个数字签名和签名算法的加密算法就是用来告知签名和算法是用哪种加密算法(一定是不可逆)加密的。

来来来,还是讲个故事比较好理解。

我的公司Alpha2Go建了个网站,然后找到了证书颁发组织SecureTrust CA要买一个SSL证书,SecureTrust CA先审核了一下我的公司和我的网站,认为我的网站合理合法且萌萌哒,所以颁发了一个数字证书(公共证书和私有证书)给我,这时我的证书的证书颁发者就是SecureTrust CA,证书拥有者就是Alpha2Go。SecureTrust CA自己拥有一个珍藏的顶级证书,这个证书的公共证书部分是被预装在OS或者browser里的。为了让我的证书更安全不会被黑客篡改,SecureTrust CA用自己的顶级证书的私钥来加密我公共证书的数字签名签名算法,并且把自己使用的加密算法的名称也放到我的公共证书里。

当我的客户通过https访问我大A站时,我的服务器会返回我的公共证书给客户端,客户端先根据我公共证书的证书颁发者找到SecureTrust CA预装在OS/Browser里的公共证书,然后用公共证书的公钥来解密之前用SecureTrust CA私钥加密的数字签名和签名算法,然后客户端用相同的签名算法得到所获的大A站证书的hash值,然后和数字签名比对,如果相同则说明证书有效,验证通过,如果无效则警告用户 FBI Warning bla bla bla

以上就是整个HTTPS的工作原理以及数字证书的内容了,还是有点小复杂的,是不?

散记