05.安全的 HTTPS

安全的 HTTPS

1. HTTP 与 HTTPS

如果在 HTTP 协议通信过程中使用未经加密的明文,比如在 Web 页面中输入信用卡号,如果这条通信线路遭到窃听,那么信用卡号就暴露了。

另外,对于 HTTP 来说,服务器也好,客户端也好,都是没有办法确认通信方的。因为很有可能并不是和原本预想的通信方在实际通信。并且还需要考虑到接收到的报文在通信途中已经遭到篡改这一可能性。

为了统一解决上述这些问题,需要在 HTTP 上再加入加密处理和认证等 机制。我们把添加了加密及认证机制的 HTTP 称为 HTTPS(HTTP Secure)。

1.1 HTTPS 是身披 SSL 外壳的 HTTP

HTTPS 并非是应用层的一种新协议。 只是 HTTP 通信接口部分用 SSL(Secure Socket Layer)和 TLS(Transport Layer Security)协议代替而已。

通常,HTTP 直接和 TCP 通信。 当使用 SSL 时, 则演变成先和 SSL 通信,再由 SSL 和 TCP 通信了。简言之,所谓 HTTPS,其实就是身披 SSL 协议这层外壳的 HTTP。

在采用 SSL 后,HTTP 就拥有了 HTTPS 的加密、证书和完整性保护这些功能。

SSL 是独立于 HTTP 的协议,所以不光是 HTTP 协议,其他运行在应用层的 SMTP 和 Telnet 等协议均可配合 SSL 协议使用。 可以说 SSL 是当今世界上应用最为广泛的网络安全技术。

1.2 加密技术

对称加密遭破解

对称加密:使用同一个密钥进行加密和解密,但是密钥被中间人拦截的话,那加密就没啥用了。

以共享密钥方式加密时必须将密钥也发给对方。可究竟怎样才能安全地转交?在互联网上转发密钥时,如果通信被监听那么密钥就可会入攻击者之手,同时也就失去了加密的意义。另外还得设法安全地保管接收到的密钥。

非对称加密遭破解

非对称加密:使用公钥加密,私钥解密。公钥可以随意发布,但私钥仅自己拥有。加密后的信息就算获取了,破解的难度也是异常困难的。

但是这也造成了一个问题,不能保证公开密钥本身就是货真价实的密钥。如果密钥被攻击者给替换了,攻击者用自己的私钥便可以顺利解密。

数字证书

保证公钥是否是原本的公钥,可以使用由数字证书认证机构(CA,Certificate Authority)和其相关机关颁发的公开密钥证书。

服务器会将这份由数字证书认证机构颁发的公钥证书发送给客户端,以进行公开密钥加密方式通信。

接到证书的客户端可使用数字证书认证机构的公开密钥,对那张证书上的数字签名进行验证,一旦验证通过, 客户端便可明确两件事: 一,认证服务器的公开密钥的是真实有效的数字证书认证机构。二,服务器的公开密钥是值得信赖的。

此处认证机关的公开密钥必须安全地转交给客户端。使用通信方式时,如何安全转交是一件很困难的事,因此,多数浏览器开发商发布版本时,会事先在内部植入常用认证机关的公开密钥。

但是问题又来了,中间人向权威机构申请了证书,并且将证书替换了怎么办?

这点也是早有准备,证书的签名由服务端网址等信息一起生成的,并且通过了机构的私钥加密,中间人无法篡改,所以假证书无法通过。

如何验证 CA 证书合法性?

https://www.zhihu.com/question/37370216/answer/1914075935

一个数字证书,通常包含了:

  • 公钥;
  • 持有者信息;
  • 证书认证机构(CA)的信息;
  • CA 对这份文件的数字签名及使用的算法;
  • 证书有效期;
  • 还有一些其他额外信息;

数字证书的作用,是用来认证公钥持有者的身份,以防止第三方进行冒充。说简单些,证书就是用来告诉客户端,该服务端是否是合法的,因为只有证书合法,才代表服务端身份是可信的。

为了让服务端的公钥被大家信任,服务端的证书都是由 CA 签名的,CA 就是网络世界里的公安局,具有极高的可信度,因此由 CA 给公钥签名,证书是可信任的。

数字证书签发和验证流程

CA 签发证书的过程,如上图左边部分:

  • 首先 CA 会把持有者的公钥、用途、颁发者、有效时间等信息打成一个包,然后对这些信息进行 Hash 计算,得到一个 Hash 值;
  • 然后 CA 会使用自己的私钥将该 Hash 值加密,生成 Certificate Signature,也就是 CA 对证书做了签名;
  • 最后将 Certificate Signature 添加在文件证书上,形成数字证书;

客户端校验服务端的数字证书的过程,如上图右边部分:

  • 首先客户端会使用同样的 Hash 算法获取该证书的 Hash 值 H1;
  • 通常浏览器和操作系统中集成了 CA 的公钥信息,浏览器收到证书后可以使用 CA 的公钥解密 Certificate Signature 内容,得到一个 Hash 值 H2 ;
  • 最后比较 H1 和 H2,如果值相同,则为可信赖的证书,否则则认为证书不可信。
证书链

但事实上,证书的验证过程中还存在一个证书信任链的问题,因为我们向 CA 申请的证书一般不是根证书签发的,而是由中间证书签发的,比如百度的证书,从下图你可以看到,证书的层级有三级:

对于这种三级层级关系的证书的验证过程如下:

  1. 客户端收到 http://baidu.com 的证书后,发现这个证书的签发者不是根证书,就无法根据本地已有的根证书中的公钥去验证 http://baidu.com 证书是否可信。于是,客户端根据 http://baidu.com 证书中的签发者,找到该证书的颁发机构是 “GlobalSign Organization Validation CA - SHA256 - G2”,然后向 CA 请求该中间证书。

  2. 请求到证书后发现 “GlobalSign Organization Validation CA - SHA256 - G2” 证书是由 “GlobalSign Root CA” 签发的,由于 “GlobalSign Root CA” 没有再上级签发机构,说明它是根证书,也就是自签证书。应用软件会检查此证书有否已预载于根证书清单上,如果有,则可以利用根证书中的公钥去验证 “GlobalSign Organization Validation CA - SHA256 - G2” 证书,如果发现验证通过,就认为该中间证书是可信的。

  3. “GlobalSign Organization Validation CA - SHA256 - G2” 证书被信任后,可以使用 “GlobalSign Organization Validation CA - SHA256 - G2” 证书中的公钥去验证 http://baidu.com 证书的可信性,如果验证通过,就可以信任 http://baidu.com 证书。

在这四个步骤中,最开始客户端只信任根证书 GlobalSign Root CA 证书的,然后 “GlobalSign Root CA” 证书信任 “GlobalSign Organization Validation CA - SHA256 - G2” 证书,而 “GlobalSign Organization Validation CA - SHA256 - G2” 证书又信任 http://baidu.com 证书,于是客户端也信任 http://baidu.com 证书。

总括来说,由于用户信任 GlobalSign,所以由 GlobalSign 所担保的 http://baidu.com 可以被信任,另外由于用户信任操作系统或浏览器的软件商,所以由软件商预载了根证书的 GlobalSign 都可被信任。

这样的一层层地验证就构成了一条信任链路,整个证书信任链验证流程如下图所示:

为什么需要证书链这么麻烦的流程?Root CA 为什么不直接颁发证书,而是要搞那么多中间层级呢?这是为了确保根证书的绝对安全性,将根证书隔离地越严格越好,不然根证书如果失守了,那么整个信任链都会有问题。

2. HTTPS 协议概述

  • http 是明文传输,敏感信息容易被中间劫持
  • https = http + 加密,劫持了也无法解密
  • 现代浏览器已开始强制 https 协议

加密方式

  • 对称加密:一个 key 同时负责加密和解密
  • 非对称加密:一对 key,A 加密以后,只能用 B 来解密
  • https 同时使用了这两种方式,先通过非对称加密打开通道后,使用客户端生成的随机码作为对称加密的 key (因为不可能被劫持,且两者都拥有相同的 key)
  • 原因在于,非对称加密的成本高,对称加密的成本低,对称加密计算量小
总流程

证书验证 -> 非对称加密 -> 对称加密

3. HTTPS 使用成本

  • 证书费用以及更新维护
  • HTTPS 降低用户访问速度
  • 消耗 CPU 资源,需要增加大量机器

4. HTTPS 对性能的影响

4.1 协议交互所增加的网络 RTT

HTTPS详解二:SSL / TLS 工作原理和详细握手过程

RTT (Round Trip Time) 往返时间,网络请求从起点到达目的地并再次返回所需的时间。

TLS 握手过程发生了什么?

我们已经知道 TLS 握手的目的是建立安全连接,那么通信双方在这个过程中究竟干了什么呢?

  • 商定双方通信所使用的的 TLS 版本 (例如 TLS1.0, 1.2, 1.3等等);
  • 确定双方所要使用的密码组合;
  • 客户端通过服务器的公钥和数字证书上的数字签名验证服务端的身份;
  • 生成会话密钥,该密钥将用于握手结束后的对称加密。

简洁版 SSL/TLS 握手详细过程
  1. **"client hello"消息:**客户端通过发送"client hello"消息向服务器发起握手请求,该消息包含了客户端所支持的 TLS 版本和密码组合以供服务器进行选择,还有一个"client random"随机字符串。
  2. **"server hello"消息:**服务器发送"server hello"消息对客户端进行回应,该消息包含了数字证书,服务器选择的密码组合和"server random"随机字符串。
  3. **验证:**客户端对服务器发来的证书进行验证,确保对方的合法身份,验证过程可以细化为以下几个步骤:
    1. 检查数字签名
    2. 验证证书链 (这个概念下面会进行说明)
    3. 检查证书的有效期
    4. 检查证书的撤回状态 (撤回代表证书已失效)
  4. **“premaster secret"字符串:**客户端向服务器发送另一个随机字符串"premaster secret (预主密钥)”,这个字符串是经过服务器的公钥加密过的,只有对应的私钥才能解密。
  5. **使用私钥:**服务器使用私钥解密"premaster secret"。
  6. 生成共享密钥:客户端和服务器均使用 client random,server random 和 premaster secret,并通过相同的算法生成相同的共享密钥 KEY
  7. **客户端就绪:**客户端发送经过共享密钥 KEY加密过的"finished"信号。
  8. **服务器就绪:**服务器发送经过共享密钥 KEY加密过的"finished"信号。
  9. **达成安全通信:**握手完成,双方使用对称加密进行安全通信。
RSA 密钥协商算法握手过程

传统的 TLS 握⼿基本都是使⽤ RSA 算法来实现密钥交换的,在将 TLS 证书部署服务端时,证书⽂件中包含⼀对公私钥,其中公钥会在 TLS 握⼿阶段传递给客户端,私钥则⼀直留在服务端,⼀定要确保私钥不能被窃取。

在 RSA 密钥协商算法中,客户端会⽣成随机密钥,并使⽤服务端的公钥加密后再传给服务端。根据⾮对称加密算法,公钥加密的消息仅能通过私钥解密,这样服务端解密后,双⽅就得到了相同的密钥,再⽤它加密应⽤消息。

  1. TLS 第一次握手

    客户端⾸先会发⼀个「Client Hello」消息,字⾯意思我们也能理解到,这是跟服务器「打招呼」。

    消息⾥⾯有客户端使⽤的 TLS 版本号、⽀持的密码套件列表,以及⽣成的随机数(Client Random),这个随机数会被服务端保留,它是⽣成对称加密密钥的材料之⼀。

  2. TLS 第二次握手

    当服务端收到客户端的「Client Hello」消息后,会确认 TLS 版本号是否⽀持,和从密码套件列表中选择⼀个密码套件,以及⽣成随机数(Server Random)。

    接着,返回「Server Hello」消息,消息⾥⾯有服务器确认的 TLS 版本号,也给出了随机数(Server Random),然后从客户端的密码套件列表选择了⼀个合适的密码套件

    密码套件基本的形式是「密钥交换算法 + 签名算法 + 对称加密算法 + 摘要算法」

    就前⾯这两个客户端和服务端相互「打招呼」的过程,客户端和服务端就已确认了 TLS 版本和使⽤的密码套件,⽽且你可能发现客户端和服务端都会各⾃⽣成⼀个随机数,并且还会把随机数传递给对⽅。

    那这个随机数有啥⽤呢?其实这两个随机数是后续作为**⽣成「会话密钥」**的条件,所谓的会话密钥就是数据传输时,所使⽤的对称加密密钥。

    然后,服务端为了证明⾃⼰的身份,会发送「Server Certificate」给客户端,这个消息⾥含有数字证书。

  3. TLS 第三次握手

    客户端验证完证书后,认为可信则继续往下⾛。接着,客户端就会⽣成⼀个新的随机数 (pre-master),⽤服务器的 RSA 公钥加密该随机数,通过「Change Cipher Key Exchange」消息传给服务端。

    服务端收到后,⽤ RSA 私钥解密,得到客户端发来的随机数 (pre-master)。

    ⾄此,客户端和服务端双⽅都共享了三个随机数,分别是 Client RandomServer Randompre-master

    于是,双⽅根据已经得到的三个随机数,⽣成会话密钥(Master Secret),它是对称密钥,⽤于对后续的 HTTP 请求/响应的数据加解密。

    ⽣成完会话密钥后,然后客户端发⼀个「Change Cipher Spec」,告诉服务端开始使⽤加密⽅式发送消息。

    然后,客户端再发⼀个「Encrypted Handshake MessageFinishd)」消息,把之前所有发送的数据做个摘要,再⽤会话密钥(master secret)加密⼀下,让服务器做个验证,验证加密通信是否可⽤和之前握⼿信息是否有被中途篡改过。

  4. TLS 第四次握手

    服务器也是同样的操作,发「Change Cipher Spec」和「Encrypted Handshake Message」消息,如果双⽅都验证加密和解密没问题,那么握⼿正式完成。

    最后,就⽤「会话密钥」加解密 HTTP 请求和响应了。

DH 密钥协商算法

使⽤ RSA 密钥协商算法的最⼤问题是不⽀持前向保密。因为客户端传递随机数(⽤于⽣成对称加密密钥的条件之⼀)给服务端时使⽤的是公钥加密的,服务端收到到后,会⽤私钥解密得到随机数。所以⼀旦服务端的私钥泄漏了,过去被第三⽅截获的所有 TLS 通讯密⽂都会被破解。

为了解决这⼀问题,于是就有了 DH 密钥协商算法,这⾥简单介绍它的⼯作流程。

客户端和服务端各⾃会⽣成随机数,并以此作为私钥,然后根据公开的 DH 计算公式算出各⾃的公钥,通过 TLS 握⼿双⽅交换各⾃的公钥,这样双⽅都有⾃⼰的私钥和对⽅的公钥,然后双⽅根据各⾃持有的材料算出⼀个随机数,这个随机数的值双⽅都是⼀样的,这就可以作为后续对称加密时使⽤的密钥。

DH 密钥交换过程中,即使第三⽅截获了 TLS 握⼿阶段传递的公钥,在不知道的私钥的情况下,也是⽆法计算出密钥的,⽽且每⼀次对称加密密钥都是实时⽣成的,实现前向保密。

4.2 加解密相关的计算耗时

浏览器计算耗时

服务端计算耗时

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值