浏览器安全:36 | HTTPS:让数据传输更安全

前言:该篇说明:请见 说明 —— 浏览器工作原理与实践 目录

   浏览器安全主要分为三大内容:页面安全系统安全网络安全。前面用四篇文章介绍了页面安全和系统安全,也聊了浏览器和 Web 开发者是如何应对各种类型的攻击,本文就来聊下网络安全协议 HTTPS。

  先从 HTTP 的明文传输的特性说起,在上一个模块的三篇文章中分析过,起初设计 HTTP 协议的目的很单纯 ——为了传输超文本文件。那时候也没有太强的加密传输的数据需求,所以 HTTP 一直保持着明文传输数据的特征。

  但这样的话,在传输过程中的每一个环节,数据都有可能被窃取或篡改,这也意味着客户端和服务器之间还可能有个中间人,在通信过程中的一切内容都在中间人的掌握中,如下图:

 中间人攻击

   从上图可看出,使用 HTTP 传输的内容很容易被中间人窃取、伪造和篡改,通常把这种攻击方式称为中间人攻击

   具体来讲,在将 HTTP 数据提交给 TCP 层后,数据会经过用户电脑、WIFI 路由器、运营商和目标服务器,在这中间的每个环节,数据都有可能被窃取或篡改。比如用户电脑被黑客安装了恶意软件,那恶意软件就能抓取和篡改所发出的 HTTP 请求的内容。或者用户一不小心连接上 WIFI 钓鱼路由器,那么数据也能被黑客抓取或篡改。

 

在 HTTP 协议栈中引入安全层

  鉴于 HTTP 的明文传输使得传输过程毫无安全性可言,且制约了网上购物、在线转账等一系列场景应用,于是逼着引入加密方案。

  从 HTTP 协议栈层面来看,可以在 HTTP层 和 TCP层 之间插入一个安全层,所有经过安全层的数据都会被加密或解密,如下图:

 HTTP VS HTTPS

  从图中可以看出 HTTPS 并非是一个新的协议,通常 HTTP 直接和 TCP 通信,而 HTTPS则先 和安全层通信,然后安全层再和 TCP 层 通信。也就是说:HTTPS 所有的安全核心都在安全层,它不会影响到上面的 HTTP 协议,也不会影响到下面的 TCP/IP,因此要搞清楚 HTTPS 是如何工作的,就要弄清楚安全层是怎么工作的。

  总的来说,安全层有两个主要的职责:

    1. 对发起 HTTP 请求的 数据进行加密操作;

    2. 对接收到 HTTP 的内容进行解密操作。

 

  知道了安全层最重要的就是加解密,那接下来就利用安全层,一步一步实现一个从简单到复杂的 HTTPS 协议。

 

第一版:使用对称加密

  提到加密,最简单的方式是使用对称加密。所谓 对称加密是指加密和解密都使用相同的密钥

  了解了对称加密,下面就使用对称加密来实现第一版的 HTTPS。

  要在两台电脑上加解密同一个文件,至少需要知道加解密方式和密钥,因此,在 HTTPS 发送数据之前,浏览器和服务器之间需要协商加密方式和密钥,过程如下:

使用对称加密实现 HTTPS

  通过上图可以看出,HTTPS 首先要先协商加解密方式,这个过程就是 HTTPS 建立安全连接的过程。为了让加密的密钥更加难以破解,我们让服务器和客户端同时决定密钥,具体过程如下:

  • 浏览器发送它所支持的加密套件列表和一个随机数 client-random,这里的加密套件是指加密的方法加密套件列表就是指浏览器能支持多少种加密方法列表
  • 服务器会从加密套件列表中选取一个加密套件,然后还会生成一个随机数 service-random,并将 service-random 和加密套件列表返回给浏览器。
  • 最后浏览器和服务器分别返回确认消息。

  

  这样客户端和服务端都有相同的 client-random 和 service-random 了,然后它们再使用相同的方法将 client-random 和 service-random 混合起来生成一个密钥 master secret,有了密钥 master secret 和加密套件之后,双方都可以进行数据的加密传输了。

   通过将对称加密应用在安全层上,实现了第一个版本的HTTPS,虽然这个版本能够很好地工作,但其中传输 client-random 和 service-random 的过程却是明文的,这意味着黑客也可以拿到协商的加密套件和双方的随机数,由于利用随机数合成密钥的算法是公开的,所以黑客拿到随机数后,也可以合成密钥,这样数据依然可以被破解,那么黑客也就可以使用密钥来伪造或篡改数据了。

  对称加密的问题:随机数明文传输,合成密钥的算法是公开的,黑客也可拿到密钥,自然就可以破解数据

 

第二版:使用非对称加密

  不过非对称加密能够解决这个问题,因此接下来就利用非对称加密来实现第二版的 HTTPS,不过在讨论具体的实现之前,先来看看什么是非对称加密?

  

  和对称加密只有一个密钥不同,非对称加密算法有 A、B 两把密钥,如果用 A 密钥来加密,那只能用 B 密钥来解密;反过来,如果用 B 密钥加密,就只能使用 A 密钥来解密

 

  在 HTTPS 中,服务器会将其中的一个密钥通过明文的形式发送给浏览器,我们把这个密钥称为公钥,服务器自己留下的那个密钥称为私钥。顾名思义,公钥是每个人都能获取到的,而私钥只有服务器才能知道,不对任何人公开。下图是使用非对称加密改造的 HTTPS 协议:

非对称加密 实现 HTTPS

根据该图,来分析下使用非对称加密的请求流程:

  • 首先浏览器还是发送加密套件给服务器;
  • 然后服务器会选择一个加密套件,不过和对称加密不同的是,使用非对称加密时服务器上需要有用于浏览器加密的公钥和服务器解密 HTTP 数据的私钥,由于公钥是给浏览器加密使用的,因此服务器会将加密套件和公钥一起发送给浏览器;
  • 最后就是浏览器和服务器返回确认消息。

  

  这样客户端就有了服务器的公钥,在客户端向服务器发送数据时,就可以使用公钥来加密数据。由于公钥加密的数据只有私钥才能解密,所以即便黑客截获了数据和公钥,也是无法使用公钥来解密数据的。

  因此采用非对称加密,就能保证浏览器发送给服务器的数据是安全的了,这看上去似乎很完美,不过这种方式依然存在两个严重的问题:

  1. 非对称加密的效率太低。这会严重影响到加解密数据的速度,进而影响到用户打开页面的速度。——为什么 非对称加密的效率太低?

  2. 无法保证服务器发送给浏览器的数据安全。虽然客户端可以使用公钥来加密,但是服务器只能采用私钥来加密,私钥加密只有公钥才能解密,但黑客也是可以获取到公钥的,这样就不能保证服务器端数据的安全了。

  非对称加密的问题:两点:1. 效率低 ; 2  服务器向浏览器传输数据仍然不安全,因为黑客可以拿到公钥,自然就可以破解 私钥加密的数据。

 

第三版:对称加密和非对称加密搭配使用

  基于以上两点原因,最终选择了一个更加完美的方案,那就是在传输数据阶段依然使用对称加密,但对称加密的密钥采用非对称加密来传输。下图就是改造后的版本:

  加密套件:加密的方法。

  加密套件列表:浏览器能支持多少种加密方法列表。

  对称加密:加解密的密钥相同,只有一把密钥

  非对称米哟昂:两把密钥,A 加密,B 解密;反正,B 加密,A 解密

混合加密实现 HTTPS

从图中可以看出,改造后的流程是这样的:

  • 首先浏览器向服务器发送对称加密套件列表、非对称加密套件列表和随机数 client-random;
  • 服务器保存随机数 client-random,选择对称加密和非对称加密的套件,然后生成随机数 service-random,向浏览器发送选择的加密套件、service-random 和公钥;
  • 浏览器保存公钥,并生成随机数 pre-master,然后利用公钥对 pre-master加密,并向服务器发送加密后的数据;
  • 最后服务器拿出自己的私钥,解密出 pre-master数据,并返回确认消息。

  到此为止,服务器和浏览器就有了共同的 client-random、service-random 和 pre-master,然后服务器和浏览器会使用这三组随机数生成对称密钥,因为服务器和浏览器使用同一套方法来生成密钥,所以最终生成的密钥也是相同的。

  有了对称加密的密钥之后,双方就可以使用对称加密的方式来传输数据了。

 

  需要特别注意的一点,pre-master 是经过公钥加密之后传输的,所以黑客无法获取到 pre-master,这样黑客就无法生成密钥,也就保证了黑客无法破解传输过程中的数据了

  对称 & 非对称组合式 问题:黑客可以通过 DNS 劫持 将 服务器IP 替换成 自己的,因客户端无法识别服务器的正式下,故 客服端访问的是 黑客的站点(服务器)。

 

第四版:添加数字证书

  通过对称和非对称混合方式,完美地实现了数据的加密传输。不过这种方式依然存在问题,比如要打开极客时间的官网,但是黑客通过 DNS 劫持将极客时间官网的 IP 地址替换成了黑客的 IP 地址,这样访问的其实是黑客的服务器了,黑客就可以在自己的服务器上实现公钥和私钥,而对浏览器来说,它完全不知道现在访问的是个黑客的站点。

 

  所以还需要服务器向浏览器提供证明“我就是我”,那如何证明?

 

  这里结合实际生活中的一个例子,比如要买房子,首先需要给房管局提交买房的材料,包括银行流水、银行证明、身份证等,然后房管局工作人员在验证无误后,会发给你一本盖了章的房产证,房产证上包含了你的名字、身份证号、房产地址、实际面积、公摊面积等信息。

  在这个例子中,之所以能证明房子是自己的,是因为引进了房管局这个权威机构,并通过这个权威机构给你颁发了一个证书:房产证。

  同理,极客时间要证明这个服务器就是极客时间的,也需要使用权威机构颁发的证书,这个权威机构称为 CA(Certificate Authority),颁发的证书就称为数字证书(Digital Certificate)

  对于浏览器来说,数字证书有两个作用:

    1. 通过数字证书向浏览器证明服务器的身份;

    2. 数字证书中包含了服务器公钥。

 

  接下来就看看含有数字证书的 HTTPS 的请求流程:

完整的 HTTPS 请求流程

相较于第三版的 HTTPS 协议,主要有两点改变:

  1. 服务器没有直接返回公钥给浏览器,而是返回了数字证书,而公钥包含在数字证书中;
  2. 在浏览器端多了一个证书验证的操作,验证了证书之后,才继续后续流程。

 

  通过引入数字证书,就实现了服务器的身份认证功能,这样即便黑客伪造了服务器,但由于证书是没有办法伪造的,所以依然无法欺骗用户。

 

数字证书的申请和验证

  通过上面四个版本的迭代,实现了目前的 HTTPS 架构。

  在第四版的 HTTPS 中,提到过,有个数字证书,黑客就无法欺骗用户了,那 数字证书又是如何证明用户身份的?

 

如何申请数字证书

  先来看看如何向 CA 申请证书。比如极客时间需要向某个 CA 去申请数字证书,通常的申请流程如下:

  • 首先极客时间需要准备一套私钥和公钥,私钥留着自己使用
  • 然后极客时间向 CA 机构提交公钥、公司、站点等信息并等待认证,这个认证过程可能是收费的;
  • CA 通过线上、线下等多种渠道来验证极客时间所提供的信息的真实性,如公司是否存在、企业是否合法、域名是否归属该企业等;
  • 如信息审核通过,CA 会向极客时间签发认证的数字证书,包含了极客时间的公钥、组织信息、CA 的信息、有效时间、证书序列号等,这些信息都是明文的,同时包含了一个 CA 生成的签名。

  这样就完成了极客时间数字证书的申请过程。前面几步都很好理解,不过最后一步数字签名的过程还需要解释下:

  • 首先 CA 使用 Hash 函数 来计算极客时间提交的明文信息,并得出信息摘要
  • 然后 CA 再使用它的私钥对信息摘要进行加密,加密后的密文就是 CA 颁给极客时间的数字签名。

  这就相当于房管局在房产证上盖的章,这个章是可以去验证的,同样,也可以通过数字签名来验证是否是该 CA 颁发的。

 

浏览器如何验证数字证书?

  有了 CA 签名过的数字证书,当浏览器向极客时间服务器发出请求时,服务器会返回数字证书给浏览器。

  浏览器接收到数字证书后,会对数字证书进行验证。首先浏览器读取证书中相关的明文信息,采用 CA 签名时相同的 Hash 函数来计算并得到信息摘要 A;然后再利用对应 CA 的公钥解密签名数据【那浏览器是如何拿到 CA 公钥的?】,得到信息摘要 B;对比信息摘要 A 和信息摘要 B,如果一致,则可以确认证书是合法的,即证明了这个服务器是极客时间的;同时浏览器还会验证证书相关的域名信息、有效时间等信息。

  这时候相当于验证了 CA 是谁,但这个 CA 可能比较小众,浏览器不知道该不该信任它,然后浏览器会继续查找给这个 CA 颁发证书的 CA,再以同样的方式验证它上级 CA 的可靠性。通常情况下,操作系统中会内置信任的顶级 CA 的证书信息(包含公钥),如果这个 CA 链中没有找到浏览器内置的顶级的 CA ,证书也会被判定非法。

  另外,在申请和使用证书的过程中,还需要注意以下三点:

  1、申请数字证书是不需要提供私钥的,要确保私钥永远只能由服务器掌握;

  2、数字证书最核心的是 CA 使用它的私钥生成的数字签名;

  3、内置 CA 对应的证书称为根证书,根证书是最权威的机构,它们自己为自己签名,我们把这称为自签名证书。

 

总结

本文的主要内容:

  由于 HTTP 的明文传输特性,在传输过程中的每个环节,数据都有可能被窃取或篡改,这逼着需要引入加密机制。于是在 HTTP 协议栈的 HTTP 层 和 TCP 层之间插入了一个安全层,负责数据的加密和解密操作。

 

  使用对称加密实现安全层,但是由于对称加密的密钥需要明文传输,所以又将对称加密改造成非对称加密。但是非对称加密效率低且不能加密服务器到浏览器的数据,于是又继续在安全层改,采用对称加密的方式加密传输数据 和 非对称加密的方式来传输密钥,这样就解决传输效率和两端数据安全传输的问题。

 

  采用这种方式虽然能保证数据的安全传输,但依然没办法证明服务器是可靠的,于是又引入了数字证书,数字证书是由 CA 签名过的,所以浏览器能够验证该证书的可靠性。

  另外百看不如一试,建议你自己亲手搭建一个 HTTPS 的站点,可以去 freeSSL 申请免费证书。链接已经放在文中:

  中文:https://freessl.cn/

  英文:https://www.freessl.com/   英文的打开有点乱码的样,建议查看中文版的。

 

思考时间

总结一下 HTTPS 的握手过程。

 

答案:

  1. 首先是 TCP 的三次握手建立连接

  2. client 发送 random1+支持的加密算法集合(clientHello)

  3. server 收到信息,返回选择一个加密算法+ random2(serverHello)+ 证书 + 确认

  4. client 验证证书有效性,并用random1 + random2 生成 pre-master 通过服务器公钥加密 发送给 server

  5. server 收到 pre-master,根据约定的加密算法对 random1 + random2 + pre-master(解密)生成master-secret,然后发送预定成功

  6. client 收到生成同样的 master-secert,对称加密密钥传输完毕。

记录

1、浏览器是如何拿到 CA 公钥的?

作者回复?

先从证书类型开始:

  我们知道 CA 是一个机构,它的职责是给一些公司或个人颁发数字证书,在颁发证书之前,有一个重要的环节,就是申请者所提交资料的合法性和合规性。不过申请者的类型有很多:

  如果申请者是个人,CA 只需要审核 域名的 所有权就行了,审核域名所有权有很多种方法,最常用的方法是让申请者在域名上放一个文件,然后 CA 验证该文件是否存在,即可证明该域名是否是申请者的。我们把这类数字证书称为 DV,审核这种个人域名信息是最简单的,因此 CA 收取的费用也是最低的,有些 CA 甚至免费为个人颁发数字证书。

  如果申请者是普通公司,那么 CA 除了验证域名的所有权外,话需要验证公司的合法性,这类证书通常称为 OV。由于需要验证公司的信息,所以需要额外的资料,而且审核过程也更加复杂,申请OV 证书的价格也更高,主要是由于验证公司的合法性是需要人工成本的。

  如果申请者是一些金融机构、银行、电商平台等,所以还需额外的验证一些经营资质是否合法合规,这类证书称为 EV。申请 EV 的价格非常高,甚至达到好几万一年,因为需要人工验证更多的内容。

  了解了证书的类型,DV 这种就可以自动审核,不过 OV、EV 这种类型的证书就需要人工验证了,而每个地方的验证方式又可能不同,比如你是一家美国本地的 CA 公司,要给中国的一些金融公司发放数字证书,这验证证书的过程中就会遇到问题,因此需要本地的 CA 机构,他们验证会更加容易。

  因此,就全球就有很多家 CA 机构,然后就出现了一些问题,这些 CA 是怎么证明它自己是安全的?如果一个恶意的公司也成立了一个 CA 机构,然后给自己颁发证书,那这就非常危险了,因此必须还要实现一个机制,让 CA 证明它自己是安全无公害的。

  这就涉及到数字证书链了。

  要讲数字证书链,就要了解我们的 CA 机构也是分两种类型的,中间 CA (Intermediates CAs) 和 根 CA (Root CAs),通常申请者都是向中间 CA 去申请证书的,而根 CA 作用就是给中间 CA 做认证,通常,一个 根 CA 会认证很多中间的CA,而这些中间 CA 又可以去认证其他的中间CA。

  比如你可以在Chrome 上打开极客时间的官网,然后点击地址栏签名的那把小锁,就可以看到*.geekbang,org 的证书是由中间 CA  GeoTrust RSA CA2018 颁发的,而中间CA GeoTrust RSA CA2018 又是由根CA DigiCert Global Root CA 颁发的,所以这个证书链就是:*.geekbang,org --->  Geo Trust RSA CA2018 ---> DigiCert Global Root CA。

  因此浏览器验证极客时间的证书时,会先验证*.geekbang,org的证书,如果合法再验证中间CA的证书,如果中间CA 也是合法的,那么浏览器会继续验证这个中间 CA的根证书。

  这时候问题又来了,怎么证明根证书是合法的?

  浏览器的做法很简单,它会查找系统的根证书,如果这个根证书在操作系统里面,那浏览器就认为这个根证书是合法的,如果验证的根证书不在操作系统里面,那就是不合法的。

  而操作系统里面这些内置的根证书也不是随便内置的,这些根CA 都是通过WebTrust 国际安全审计认证。

  那么什么又是 WebTrust认证?

  WebTrust(网络信任)认证是电子认证服务行业中唯一的国际性认证标准,主要对互联网服务商的系统及业务运作的商业惯例和信息隐私,交易完整性和安全性。WebTrust 认证是各大主流的浏览器、微软等大厂商支持的标准,是规范CA 机构运营服务的国际标准。在浏览器厂商根证书植入项目中,必要的条件就是要通过WebTrust 认证,才能实现浏览器与数字证书的无缝嵌入。

  目前通过WebTrust 认证的根CA有Comodo,geotrust,rapidssl,symantec,thawte,digicert 等。也就是说,这些根 CA 机构的根证书都内置在各大操作系统中,只要能从数字证书链往上追溯到这几个根证书,浏览器会认为使用者的证书是合法的。

 

2、主线程和渲染引擎、JS引擎线程之间有什么关系?渲染引擎和 JS 引擎互斥,两个引擎是都运行在主线程中吗?这个主线程到底是什么?

作者回复:

  首先,渲染进程有个主线程,DOM 解析,样式计算,执行 JS,执行垃圾回收等等操作都是在这个主线程上执行的,

  没有所谓的渲染引擎线程和 JS 引擎线程的概念,你可以把渲染和执行 JS 看成是一种功能,如果要执行这些功能的话,需要在一个线程上执行,在Chrome 中,它们都是执行在渲染进程的主线程上。

  正是因为它们都是执行在同一个线程上的,所以同一时刻只能运行一个功能,也就是你说的互斥。

 

3、为什么 HTTPS 的非对称加密比对称加密慢? (答案摘录:https://www.jianshu.com/p/4dfcddc7e8ce)——看着是解释的很清楚, 反正我是没怎么明白,主要是涉及到知识盲区了。

对称加密主要的运算是位运算,速度非常快,如果使用硬件计算,速度会更快。以 AES (AES: 高级加密标准)算法为例,如下图:其运算本质上来说就是位移和替换

 

但是非对称加密计算一般都比较复杂,比如 RSA(非对称加密算法),它里面涉及到大数乘法、大数模等等运算,其加解密可以用下面的公式来表示:

 

  我们知道,幂运算的本质是乘法,乘法的基础单位是加法,也就是最常见的整数加。学过数字逻辑电路的想必都知道,在电路上实现“加法”比异或(XOR)要麻烦的多,况且后面还有一个模运算。因此非对称加密的速度自然比对称加密慢。

  当然,我想还有另外一个原因是,AES 中的许多中间计算过程是可以事先计算好的。加密数据时许多中间过程可以直接查表,而不需要实时地计算。

  这里另外提一点,在学习算法的时候,一定听过时间复杂度和空间复杂度这两个名词。(后续需要学下这两块的知识)。鱼与熊掌不可兼得,一般情况下,一个算法如果运算比较快,那么空间消耗相对来说就会高一点,反之亦然。因此才有拿空间换时间的说法。

posted on 2022-04-06 16:55  bala001  阅读(487)  评论(0编辑  收藏  举报

导航