计算机网络系列 -- HTTPS

357 阅读17分钟

关于HTTP的详细内容见 计算机网络系列 -- HTTP

本文大部分内容参考于 彻底搞懂HTTPS的加密原理 这篇文章

HTTPS 的定义

HTTPS 是以安全为目标的 HTTP 通道,在HTTP的基础上通过传输加密身份认证保证了传输过程的安全性。HTTPS 在HTTP 的基础下加入 SSL,HTTPS 的安全基础是 SSL,因此加密的详细工作就由 SSL 协议来完成

HTTPS协议 = HTTP协议 + SSL协议,在HTTPS数据传输的过程中

  • 利用SSL 协议对数据进行加密解密
  • 利用HTTP 协议对加密后的数据进行传输 由此可以看出 HTTPS 是由 HTTP 和 SSL 一起合作完成

SSL 的定义

SSL 及其继任者 TLS 是为网络通信提供一种能保证数据安全数据完整性安全协议。TLS 与 SSL 在传输层应用层之间对网络连接进行加密 image.png

HTTPS 对 HTTP 的改进

HTTPS 对 HTTP 的改进体现在三个点上:

  1. 数据安全:采用混合加密技术,中间者无法直接查看明文内容
  2. 身份验证:通过证书认证客户端访问的是自己的服务器
  3. 数据完整性:防止传输的内容被中间人冒充或者篡改 例如:通过抓包可以看到数据不是明文传输

image.png

HTTPS 是如何保证安全性的

  1. HTTPS 的安全性在于它是采用非对称加密和对称加密两种方案混合的方式进行数据传输的
  2. 首先公钥、私钥都在服务器那里,浏览器请求URL就是请求服务器给个公钥,浏览器用公钥加密,服务器私钥解密,这个过程是在传输密钥
  3. HTTPS 的安全性关键取决于非对称加解密过程的安全性,浏览器是通过查数字证书的颁发者的信息和服务器的信息做对比,验查是否被调包
  4. 浏览器还通过数字签名映射出数字证书的原始内容和拿到的证书内容做对比,验查是否被篡改
  5. 一旦发现证书被调包/篡改,都终止交易,不传密钥

接下来我们从【密码学】、【对称加密】、【非对称加密】、【数字证书】、【数字签名】层层深入,最终总结出【SSL 握手的全过程】,从而得出 HTTPS 是具体如何保证 数据安全身份验证数据完整性 的:

密码学的一些概念

  • 明文: 明文指的是未被加密过的原始数据。
  • 密文:明文被某种加密算法加密之后,会变成密文,从而确保原始数据的安全。密文也可以被解密,得到原始的明文。
  • 密钥:密钥是一种参数,它是在明文转换为密文或将密文转换为明文的算法中输入的参数。密钥分为对称密钥与非对称密钥,分别应用在对称加密和非对称加密上。
  • 对称加密:对称加密又叫做密钥加密,即信息的发送方和接收方使用同一个密钥去加密和解密数据。对称加密的特点是算法公开、加密和解密速度快,适合于对大数据量进行加密,常见的对称加密算法有DES、3DES、TDEA、Blowfish、RC5和IDEA。
  • 其加密解密过程如下:

明文 + 加密算法 + 密钥 => 密文密文 + 解密算法 + 密钥 => 明文

其加密过程中的私钥与解密过程中用到的密钥是同一个,这也是称加密之所以称之为“对称”的原因。

  • 非对称加密:。非对称加密与对称加密相比,其安全性更好。因为对称加密的通信双方使用相同的密钥,如果一方的密钥遭泄露,那么整个通信就会被破解。而非对称加密使用一对密钥,即公钥和私钥,且二者成对出现。私钥被自己保存,不能对外泄露。公钥指的是公开的密钥,任何人都可以获得该密钥。用公钥或私钥中的任何一个进行加密,用另一个进行解密。

  • 被公钥加密过的密文只能被私钥解密,过程如下:

明文 + 加密算法 + 公钥 => 密文密文 + 解密算法 + 私钥 => 明文

  • 被私钥加密过的密文只能被公钥解密,过程如下:

明文 + 加密算法 + 私钥 => 密文密文 + 解密算法 + 公钥 => 明文

由于加密和解密使用了两个不同的密钥,这就是非对称加密“非对称”的原因,注意两种密钥都可以加密和解密:公钥加密对应私钥解密私钥加密对应公钥解密

HTTPS同时采用非对称加密对称加密

为什么要采用 非对称加密 和 对称加密 混合加密

只用对称加密方案可行吗?

如果通信双方都各自持有同一个密钥,且没有别人知道,这两方的通信安全当然是可以被保证的(除非密钥被破解)。

然而最大的问题就是这个密钥怎么让传输的双方知晓,同时不被别人知道。如果由服务器生成一个密钥并传输给浏览器,那在这个传输过程中密钥被别人劫持到手了怎么办?之后他就能用密钥解开双方传输的任何内容了,所以这么做当然不行。

换种思路?试想一下,如果浏览器内部就预存了网站A的密钥,且可以确保除了浏览器和网站A,不会有任何外人知道该密钥,那理论上用对称加密是可以的,这样浏览器需要预存好世界上所有HTTPS网站的密钥!这么做显然不现实。 怎么办?所以我们就需要非对称加密

只用非对称加密方案可行吗

鉴于非对称加密的机制,我们可能会有这种思路:服务器事先存有公钥和私钥,服务端先把公钥以明文方式传输给浏览器,之后浏览器向服务器传数据前都先用这个公钥加密好再传,这样由浏览器向服务器传输数据的安全就可以保障了!因为只有服务器有相应的私钥能解开公钥加密的数据。

然而由服务器到浏览器的这条路怎么保障安全?如果服务器用它的私钥加密数据传给浏览器,那么浏览器用公钥可以解密它,而这个公钥是一开始通过明文传输给浏览器的,若这个公钥被中间人劫持到了,那他也能用该公钥解密服务器传来的信息了。所以这样不能保障由服务器到浏览器的这条路的安全性

改进后的非对称加密方案可行吗

就是浏览器和服务器各有一套公钥和私钥,这样就可以保证两条路的安全

  1. 某网站服务器拥有公钥A与对应的私钥A’;浏览器拥有公钥B与对应的私钥B’。。
  2. 浏览器把公钥B明文传输给服务器。
  3. 服务器把公钥A明文给传输浏览器。
  4. 之后浏览器向服务器传输的内容都用公钥A加密,服务器收到后用私钥A’解密。由于只有服务器拥有私钥A’,所以能保证这条数据的安全。
  5. 同理,服务器向浏览器传输的内容都用公钥B加密,浏览器收到后用私钥B’解密。同上也可以保证这条数据的安全 但是为什么不采用这种方案呢?原因是非对称加密非常耗时,相比之下对称加密就比较省时快,那么如何利用对称加密的省时结合非对称加密的安全呢?

耗时的原因在于:非对称加密中 辨认公钥的真伪 十分麻烦,后面会讲到虽然使用数字证书能保证公钥不被调包,但是同时引发出两个点:1. 如何辨别证书是否被调包;2. 如何辨别证书是否被篡改

非对称加密 + 对称加密 方案的优点

  • 安全
  1. 某网站拥有用于非对称加密的公钥A、私钥A’。
  2. 浏览器向网站服务器请求,服务器把公钥A明文给传输浏览器。
  3. 浏览器随机生成一个用于对称加密的密钥X,用公钥A加密后传给服务器。
  4. 服务器拿到后用私钥A’解密得到密钥X。
  5. 这样双方就都拥有密钥X了,且别人无法知道它。之后双方所有数据都通过密钥X加密解密即可 综上所述:为了安全效率,HTTPS同时采用非对称加密对称加密技术:
  • 对称加密:利用客户端创建的密钥对数据进行加密,而客户端需要通过发送请求事先告知服务端秘钥
  • 非对称加密:利用证书的公钥和私钥分别对密钥进行加解密,以保证秘钥不会被窃取
  • 之后的数据传输都是利用密钥对数据进行对称加密,然后HTTP负责传输

仍有安全漏洞 —— 中间人调包公钥

image.png

  1. 黑客拦截服务端发来的公钥
  2. 自己伪造的的公钥并发给客户端
  3. 客户端无法辨别公钥来源,就用公钥加密秘钥
  4. 黑客拦截客户端发来的已加密秘钥,通过自己的私钥解密获得秘钥(关键步)
  5. 黑客用之前拦截获得的公钥加密秘钥发给服务端

这样在双方都不会发现异常的情况下,中间人掉包了服务器传来的公钥,进而得到了密钥X。根本原因是浏览器无法确认收到的公钥是不是网站自己的,因为公钥本身是明文传输的

那么如何证明浏览器收到的公钥一定是该网站的公钥?

其实道理就跟如何证明小明出示的身份证一定是小明的,而不是自己伪造的身份证。方法就是看身份证上面印有政府机关公认的印章等等。那么同理,如何给网站颁发一个“身份证”呢?能否有个机构充当互联网世界的“公理”呢?

有,它就是CA机构,它是如今互联网世界正常运作的前提,而CA机构颁发的“身份证”就是数字证书

数字证书

网站在使用HTTPS前,需要向CA机构申领一份数字证书,数字证书里含有证书持有者信息公钥信息服务器域名权威机构的信息,还有经过CA私钥签名之后的证书内容,签名计算方法。服务器把证书传输给浏览器,浏览器从证书里获取公钥就行了,证书就如身份证,证明“该公钥对应该网站”。但是又有新的问题来了,证书本身的传输过程中,如何防止被篡改呢?

如何防止数字证书被篡改?

我们把证书原本的内容生成一份“签名”,比对证书内容和签名是否一致就能判别是否被篡改。这就是数字证书的“防伪技术”,这里的“签名”就叫数字签名

什么是数字签名

图中左侧是数字签名的制作过程,右侧是验证过程

image.png 数字签名的制作过程:

  1. CA机构拥有非对称加密的私钥公钥
  2. CA机构通过hash算法对证书明文数据T进行hash得到散列值
  3. 对散列值用私钥加密,得到数字签名S明文T数字签名S共同组成了数字证书,这样一份数字证书就可以颁发给网站了。 那浏览器拿到服务器传来的数字证书后,如何验证它是不是真的?(有没有被篡改、掉包)

浏览器验证过程:

  1. 拿到证书,得到明文T,签名S。
  2. 用CA机构的公钥对S解密(由于是浏览器信任的机构,所以浏览器保有它的公钥。详情见下文),得到S’。
  3. 用证书里指明的hash算法对明文T进行hash得到T’。 显然通过以上步骤,
  • 如果S’等于T’,则表明证书可信
  • 如果S’不等于T’,则表明该证书有可能被篡改了,不可信。

为什么这样可以保证证书可信呢?

通过数字签名的方式如何判断出证书被篡改了的?

假设中间人篡改了证书的原文,其对应的散列值就会发生改变,但他由于没有CA机构的私钥无法相应地篡改签名S。浏览器收到该证书后会发现原文和签名解密后的值不一致,则说明证书已被篡改,证书不可信,从而终止向服务器传输信息,防止信息泄露给中间人。

既然不可能篡改,那整个证书被掉包呢?

中间人有可能把证书掉包吗? 假设有另一个网站B也拿到了CA机构认证的证书,它想劫持网站A的信息。于是它成为中间人拦截到了A传给浏览器的证书,然后替换成自己的证书,传给浏览器,之后浏览器就会错误地拿到B的证书里的公钥了,这确实会导致上文“中间人攻击”那里提到的漏洞?

其实这并不会发生,因为证书里包含了网站A的信息,包括域名,浏览器把证书里的域名自己请求的域名比对一下就知道有没有被掉包了。

为什么制作数字签名时需要hash一次?

似乎以上过程中hash有点多余,把hash过程去掉也能保证证书没有被篡改。

最显然的是性能问题,前面我们已经说了非对称加密效率较差,证书信息一般较长,比较耗时。而hash后得到的是固定长度的信息(比如用md5算法hash后可以得到固定的128位的值),这样加解密就快很多。

当然也有安全上的原因,这部分内容相对深一些,感兴趣的自行去了解

怎么证明CA机构的公钥是可信的?

你们可能会发现上文中说到CA机构的公钥,我几乎一笔带过,“浏览器保有它的公钥”,这是个什么保有法?怎么证明这个公钥是否可信?

让我们回想一下数字证书到底是干啥的?没错,为了证明某公钥是可信的,即“该公钥是否对应该网站”,那CA机构的公钥是否也可以用数字证书来证明?没错,操作系统、浏览器本身会预装一些它们信任的根证书,如果其中会有CA机构的根证书,这样就可以拿到它对应的可信公钥了。

实际上证书之间的认证也可以不止一层,可以A信任B,B信任C,以此类推,我们把它叫做信任链或数字证书链。也就是一连串的数字证书,由根证书为起点,透过层层信任,使终端实体证书的持有者可以获得转授的信任,以证明身份。

另外,不知你们是否遇到过网站访问不了、提示需安装证书的情况?这里安装的就是根证书。说明浏览器不认给这个网站颁发证书的机构,那么你就得手动下载安装该机构的根证书(风险自己承担)。安装后,你就有了它的公钥,就可以用它验证服务器发来的证书是否可信了。

image.png

综上所述:HTTPS 握手具体过程

image.png

一、事先对接用于对称加密解密的算法

  1. 客户端发送自己支持的一些对称加解密算法(一个集合)给服务端

  2. 服务端从集合里面挑选出一个对称加解密算法,然后发回给客户端,这样客户端和服务端之间就互通了后面对称加密用哪个算法了 二、对接用于非对称加密的证书

  3. 随后服务端再把数字证书传输给客户端,私钥自己留着。(证书内容包括服务器域名、公钥、证书有效期)

  4. 客户端解析证书,需要检测的内容有:证书里的域名自己请求的域名比对一下(防止证书被调包),证书明文数据hash之后对应的散列值与解密得到的数字签名两者进行对比(防止证书信息被篡改),过期时间等等,如果发现异常,则会弹出一个警告框,提示证书存在问题。

三、生成秘钥,然后非对称加密传输

  1. 如果证书没有问题,那么客户端就会生成密钥(一串随机数的密码),并用证书中提供的公钥加密,然后全部发送给服务端
  2. 服务端收到之后也是先检测证书:对比证书里的域名自己的域名以及证书明文数据hash之后对应的散列值与解密得到的数字签名防止证书被篡改或调包,然后再用私钥解开获得秘钥

生成随机密钥是为了保证唯一性随机性(安全)

四、确认双方各自的收发能力

  1. 客户端通过会话秘钥加密一条消息发送给服务端,主要验证服务端是否正常接受客户端加密的消息。
  2. 同样服务端也会通过会话秘钥加密一条消息回传给客户端,如果客户端能够正常接受的话表明TLS层连接建立已完成(剩余两次握手)

五、握手完成,传输对称加密数据

  1. 发送数据:客户端与服务器双方每次发送数据之前,都会对 明文 和之前对接好的 密钥 运用之前对接好的 对称加密算法 进行加密得到 密文
  2. 接收数据之前,双方都会对收到的 密文 和之前对接好的 密钥 运用之前对接好的 对称解密算法 进行解密得到 明文

每次进行HTTPS请求时都必须在SSL/TLS层进行握手传输密钥吗?

  1. 服务端会为每个浏览器(统称客户端)各自维护一个 session,在 SSL 握手过程中,服务端收到客户端发来的密钥后,会把该密钥存到相应的 session 下
  2. 并生成相应的session ID然后发给客户端
  3. 之后浏览器每次请求都会携带session ID
  4. 服务器会根据session ID 找到相应的密钥 并进行解密加密操作,这样就不必每次传输数据都要重新制作、传输密钥了(非对称加密很耗时)

运用与总结

HTTPS 虽然保证了 数据安全、身份验证、数据完整性,但其实也会引发一些问题:

  • 成本上:证书费用
  • 时间上:HTTPS 握手阶段相比 HTTP 比较耗时,对网站的响应速度有影响,可能会影响用户体验

所以我们采用分而治之的策略:

  • 用户浏览的部分用 HTTP 传输
  • 涉及用户信息、用户金额方面用 HTTPS 传输

问题回顾

  1. 为什么不能只用非对称加密?
  2. 为什么要用对称加密+非对称加密?
  3. 为什么需要数字证书?
  4. 为什么需要数字签名?

参考文章