HTTPS协议-加密原理与交互流程

391 阅读11分钟

HTTPS协议

由于HTTP协议在通信过程中,是基于明文通信,并且底层是基于TCP/IP协议进行通信,那么按照 TCP/IP 协议族的工作机制,通信内容在所有的通信线路上都有可能遭到拦截和窃取。 窃取这个过程其实很简单,通过抓包工具Wireshark就可以截获请求和响应的内容。

https 安全传输协议

由于 HTTP 协议通信的不安全性,所以人们为了防止信息在传输过程中遭到泄漏或者篡改, 就想出来对传输通道进行加密的方式https。

https是一种加密的超文本传输协议,它与HTTP在协议差异在于对数据传输的过程中,https 对数据做了完全加密。由于http协议或者https协议都是处于TCP传输层之上,同时网络协 议又是一个分层的结构,所以在 tcp 协议层之上增加了一层 SSL(Secure Socket Layer,安全层)或者TLS(Transport Layer Security)

安全层传输协议组合使用用于构造加密通道; Ssl 是 netscape 公司设计的(Secure sockets layer),后来互联网标准化组织 ISOC 接替了 NETScape公司,发布了SSL的升级版TLS。接着TLS的版本又进行了多次升级; 实际上我 们现在的 HTTPS 都是用的 TLS 协议,但是由于 SSL 出现的时间比较早,并且依旧被现在浏览器所支持,因此SSL依然是HTTPS的代名词。

逆向推导 https 的设计过程

  • 我们先不想ssl是如何实现的,假设我们需要自己在http协议的基础上对数据进行加密我们该如何去做?

从第一个消息开始

客户端A向服务端B发送一条消息,这个消息可能会被拦截以及篡改,我们如何做到A发送给B的数据包,及时被拦截了,也没办法得知消息内容并且也不能查看呢?

使用对称密钥

要做到消息不能被第三方查看以及篡改,那么第一想法就是对内容进行加密,同时,该消息还需要能被服务端进行解密。所以我们可以使用对称加密算法来实现,密钥 S 扮演着加密和解密的角色。在密钥S不公开的情况下,就可以保证安全性?

  • 在互联网的世界中永远不可能只有一台客户端,一定是很多很多
  • 那么这种情况下密钥不公开就相当于一个笑话了。
  • 黑客拿到对称密钥,就可以得到想要的任何数据
  • 那么一个密钥不行,我们给每个客户端都准备一个密钥。
  • 问题又来了,客户端怎么知道到底使用什么密钥,那么首先想到的办法就是协商。
  • 协商过程又是不安全的
  • 第一次向服务端询问密钥的时候,肯定是明文协议,那么就可以拦截到这个请求,用自己的密钥进行掉包,然后返回给客户端,客户端用该密钥进行加密返回给中间端,然后在进行解密加密,返回给服务端,拿到真实数据。

  • 黑客很轻松就能拿到数据

  • 第二个问题,服务端存放这么多密钥消耗了这么大的空间,并且保存了这么多的解密算法,太浪费了。

非对称加密

非对称加密算法的特点是:私钥加密后的密文,只要有公钥,都能解密,但是公钥加密后的密文,只有私钥可以解密。私钥只有一个人有,而公钥可以发给所有人

这样就可以保证A/B向服务器端方向发送的消息是安全的。似乎我们通过非对称加密算法解决了密钥的协商的问题?

  • 但是第一个问题又出来了,公钥怎么保证不被黑客拿到,如何黑客拿到公钥,拦截到服务端返回的信息又可以用公钥解密。

那么我们逐步思考,有两种我们能想到的方案:

  1. 服务器端将公钥发送给每一个客户端
  2. 服务器端将公钥放到一个远程服务器,客户端可以请求到 (多了一次请求,还得解决公钥 放置问题)

方案一肯定不行,传输过程不安全,公钥可能会被调包 方案二的思想貌似可行,我们可以找一个绝对信任的第三方机构

  • 引入第三方机构

到上面这一步,最关键的问题是,客户端如何知道给我公钥到底是不是真的?只能找本人去证实?或者有一个第三者来帮你证实,并且第三者是绝对公正的。 所以,引入一个可信任的第三者是一个好的方案

服务端把需要传递给客户端的公钥,通过第三方机构提供的私钥对公钥内容进行加密后,再传递给客户端? 通过第三方机构私钥对服务端公钥加密以后的内容,就是一个简陋版本的 “数字证书”。这个帧数中包含【服务器公钥】

客户端拿到这个证书以后,因为证书是第三方机构使用私钥加密的。客户端必须要有第三方机构提供的公钥才能解密证书。这块又涉及到第三方机构的公钥怎么传输?(假设是先内置 在系统中)以及还有一个问题,第三方机构颁发的证书是面向所有用户,不会只针对一家发放。如果不法分子也去申请一个证书呢?

  • 如果不法分子也拿到证书?

如果不法分子也申请了证书,那它可以对证书进行调包。客户端在这种情况下是无法分辨出收到的是你的证书,还是中间人的。因为不论是中间人的、还是你的证书都能使用第三方机构的公钥进行解密。

  • 验证证书的有效性

事情发展到现在,问题演变成了,客户端如何识别证书的真伪?在现实生活中,要验证一个 东西的真伪,绝大部分都是基于编号去验证(比如大学毕业证书,比如买的数码产品是否是山寨),

我之前讲过,计算机领域的解决方案都是人为去实现的,所以在这里,解决方案也是一样,如果给这个数字证书添加一个证书编号?是不是就能达到目的呢? 证书上写了如何根据证书的内容生成证书编号。客户端拿到证书后根据证书上的方法自己生成一个证书编号,如果生成的证书编号与证书上的证书编号相同,那么说明这个证书是真实的。

这块有点类似于md5的验证,我们下载一个软件包,都会提供一个md5的值,我们可以拿到这个软件包以后通过一个第三方软件去生成一个 md5 值去做比较,是不是一样如果一样表示这个软件包没被篡改过

对发送给服务端的数据进行 MD5 算法得到一个 MD5的值,生成证书编号,使用第三方机构 的私钥对这个证书编号进行加密,并且会在证书中添加证书编号的生成算法

浏览器内置的 CA 公钥可以解密服务端 CA 私钥加密的证书,通过浏览器内置的 CA 证书的证书编号算法对服务端返回的证书编号进行验签

  • 第三方机构的公钥证书存哪里?

浏览器和操作系统都会维护一个权威的第三方机构列表(包括他们的公钥) 因为客户端接收到的证书中会些颁发机构,客户端就根据这个办法机构的值在本地找到响应 的公钥说到这里,我想大家一定知道,证书就是HTTPS中的数字证书,证书编号就是数字签名,而第三方机构就是数字证书的签发机构(CA)

  • Google浏览器内置证书

Https 原理分析

服务端 HTTPS 证书的申请过程

  1. 服务器上生成 CSR 文件(证书申请文件,内容包括证书公钥、使用的 Hash 签名算法、申请的域名、公司名称、职位等信息)
  2. 把 CSR 文件和其他可能的证件上传到 CA 认证机构,CA 机构收到证书申请之后,使用申请中的 Hash 算法,对部分内容进行摘要,然后使用 CA 机构自己的私钥对这段摘要信息进行签名(相当于证书的唯一编号)
  3. 然后 CA 机构把签名过的证书通过邮件形式发送到申请者手中。
  4. 申请者收到证书之后部署到自己的 web 服务器中

客户端请求交互流程

  1. 客户端发起请求(Client Hello包)

a) 三次握手,建立TCP连接

b) 支持的协议版本(TLS/SSL)

c) 客户端生成的随机数client.random,后续用于生成“对话密钥”

d) 客户端支持的加密算法

e) sessionid,用于保持同一个会话(如果客户端与服务器费尽周折建立了一个HTTPS链接, 刚建完就断了,也太可惜)

  1. 服务端收到请求,然后响应(Server Hello)

a) 确认加密通道协议版本

b) 服务端生成的随机数server.random,后续用于生成“对话密钥”

c) 确认使用的加密算法(用于后续的握手消息进行签名防止篡改)

d) 服务器证书(CA机构颁发给服务端的证书)

  1. 客户端收到证书进行验证

a) 验证证书是否是上级 CA 签发的, 在验证证书的时候,浏览器会调用系统的证书管理器 接口对证书路径中的所有证书一级一级的进行验证,只有路径中所有的证书都是受信的, 整个验证的结果才是受信

b) 服务端返回的证书中会包含证书的有效期,可以通过失效日期来验证 证书是否过期

c) 验证证书是否被吊销了

d) 前面我们知道CA机构在签发证书的时候,都会使用自己的私钥对证书进行签名证书里的签名算法字段 sha256RSA 表示CA机构使用sha256对证书进行摘要,然后 使用 RSA 算法对摘要进行私钥签名,而我们也知道 RSA 算法中,使用私钥签名之后,只有公钥才能进行验签。

e) 浏览器使用内置在操作系统上的CA机构的公钥对服务器的证书进行验签。确定这个证 书是不是由正规的机构颁发。验签之后得知CA机构使用sha256进行证书摘要,然后 客户端再使用sha256对证书内容进行一次摘要,如果得到的值和服务端返回的证书验签之后的摘要相同,表示证书没有被修改过

f) 验证通过后,就会显示绿色的安全字样

g) 客户端生成随机数,验证通过之后,客户端会生成一个随机数pre-master secret,客户端根据之前的:Client.random + sever.random + pre-master生成对称密钥然后使用证书中的公钥进行加密,同时利用前面协商好的 HASH 算法,把握手消息取 HASH 值, 然后用 随机数加密 “握手消息+握手消息 HASH 值(签名)” 并一起发送给服务端 ( 在这里之所以要取握手消息的 HASH 值,主要是把握手消息做一个签名,用于验证握手消息在传输过程中没有被篡改过。 )

  1. 服务端接收随机数

a) 服务端收到客户端的加密数据以后,用自己的私钥对密文进行解密。然后得到client.random/server.random/pre-master secret, HASH值,并与传过来的HASH值做 对比确认是否一致。

b) 然后用随机密码加密一段握手消息(握手消息+握手消息的HASH值 )给客户端

  1. 客户端接收消息

a) 客户端用随机数解密并计算握手消息的 HASH,如果与服务端发来的 HASH 一致,此时握手过程结束,

b) 之 后 所 有 的 通 信 数 据 将 由 之 前 交 互 过 程 中 生 成 的 pre master secret / client.random/server.random通过算法得出session Key,作为后续交互过程中的对称密钥

证书

在生产环境中的SSL 证书都需要通过第三方认证机构购买,分为专业版 OV 证书(浏览器地 址栏上不显示企业名称)和高级版EV(可以显示企业名称)证书,证书所保护的域名数不同 也会影响价格(比如只对www认证和通配*认证,价格是不一样的),且不支持三级域名。代 表证书过期或者无效,如果是黄色的话代表网站有部分连接使用的仍然是http协议。