Go语言中文网,致力于每日分享编码、开源等知识,欢迎关注我,会有意想不到的收获!

接着上篇:HTTPS 温故知新(三)——直观感受 TLS 握手流程(上)

四. 直观感受 TLS 1.2 首次握手流程

至此,TLS 1.2 首次握手的所有细节都已经分析完了。这一节让我们小结一下上面的流程,并用 Wireshark 直观感受一下 TLS 1.2 协议。

首先是基于 RSA 密钥协商算法的首次握手:

握手开始,Client 先发送 ClientHello ,在这条消息中,Client 会上报它支持的所有“能力”。client_version 中标识了 Client 能支持的最高 TLS 版本号;random 中标识了 Client 生成的随机数,用于预备主密钥和主密钥以及密钥块的生成,总长度是 32 字节,其中前 4 个字节是时间戳,后 28 个字节是随机数;cipher_suites 标识了 Client 能够支持的密码套件。extensions 中标识了 Client 能够支持的所有扩展。

关于 extensions 本篇文章涉及的少,因为笔者打算把 TLS 1.2 和 TLS 1.3 中涉及到的 extensions 都整理到一篇文章中,在这篇握手的流程中没有详细分析。extensions 更加详细的分析请见 《HTTPS 温故知新(六) —— TLS 中的 Extensions》

Server 在收到 ClientHello 之后,如果能够继续协商,就会发送 ServerHello,否则发送 Hello Request 重新协商。在 ServerHello 中,Server 会结合 Client 的能力,选择出双方都支持的协议版本以及密码套件进行下一步的握手流程。server_version 中标识了经过协商以后,Server 选出了双方都支持的协议版本。random 中标识了 Server 生成的随机数,用于预备主密钥和主密钥以及密钥块的生成,总长度是 32 字节,其中前 4 个字节是时间戳,后 28 个字节是随机数;cipher_suites 标识了经过协商以后,Server 选出了双方都支持的密码套件。extensions 中标识了 Server 处理 Client 的 extensions 之后的结果。

当协商出了双方都能满足的密钥套件,根据需要 Server 会发送 Certificate 消息。Certificate 消息会带上 Server 的证书链。Certificate 消息的目的一是为了验证 Server 身份,二是为了让 Client 根据协商出来的密码套件从证书中获取 Server 的公钥。Client 拿到 Server 的公钥和 server 的 random 会生成预备主密钥。

由于密钥协商算法是 RSA,需要 Server 在发送完 Certificate 消息以后就直接发送 ServerHelloDone 消息了。

Client 收到 ServerHelloDone 消息以后,会开始计算预备主密钥,计算出来的预备主密钥会经过 RSA/ECDSA 算法加密,并通过 ClientKeyExchange 消息发送给 Server。RSA 密码套件的预备主密钥是 48 字节。前 2 个字节是 client_version,后 46 字节是随机数。Server 收到 ClientKeyExchange 消息以后就会开始计算主密钥和密钥块了。同时 Client 也会在自己本地算好主密钥和密钥块。

有些人会说“主密钥和会话密钥”,这里的会话密钥和密钥块是相同的意思。主密钥是由预主密钥、客户端随机数和服务器随机数通过 PRF 函数来生成;会话密钥是由主密钥、客户端随机数和服务器随机数通过 PRF 函数来生成。

会话密钥 = key_block = 密钥块,这三者的意思是一样的,只是翻译不同罢了。

Client 发送完 ClientKeyExchange 消息紧接着还会继续发送 ChangeCipherSpec 消息和 Finished 消息。Server 也会回应 ChangeCipherSpec 消息和 Finished 消息。如果 Finished 消息校验完成以后,代表握手最终成功。

再来看看基于 DH 密钥协商算法的首次握手:

基于 DH 密钥协商算法和基于 RSA 密码协商的区别在 Server 和 Client 协商 DH 参数上面。这里只说明一下 DH 密钥协商过程比 RSA 多的几步,其他的流程和 RSA 的流程基本一致。

在 Server 发送完 Certificate 消息以后,还会继续发送 ServerKeyExchange 消息,在这条消息里面传递 DH 参数。

另外一个不同点在于 ClientKeyExchange 消息中传递给 Server 预备主密钥长度不是 48 字节。基于 DH/ECDH 算法的协商密钥长度取决于 DH/ECDH 算法的公钥。

为了让读者能更加直观的理解 TLS 1.2 的流程,笔者用 Wireshark 抓取了 Chrome 和笔者博客 TLS 握手中的网络包。结合 Wireshark 的抓包分析,让我们更加深入的理解 TLS 1.2 握手吧。下面的例子以 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 密码套件为例:

上面这是一次从 TLS 握手开始到 TCP 4 次挥手完整的过程。这里我们重要关注 protocol = TLS 1.2 的所有消息。整体流程和上面分析的基于 DH 密钥交换算法的是一致的。在 TCP 4 次挥手之前,TLS 层会先收到 Close Notify 的 Alert 消息。

读到这里能有读者有疑问,为什么经过 TLS 加密以后的上层数据会以明文展示在抓包中?HTTPS 不安全?这里需要解释一下,因为笔者利用 export SSLKEYLOGFILE=/Users/XXXX/sslkeylog.log把 ECDHE 协商的密钥保存成 log 文件了,解析上层 HTTP/2 的加密包的时候就可以利用 log 中的 TLS key 进行解密。上图中绿色的部分,就是通过解密出来得到的 HTTP/2 的解密内容。具体这块内容笔者会在 HTTP/2 相关的文章里面会提一提,这里读者就认为是笔者利用某些手段解析出了 HTTPS 加密的内容即可。

接下来一条条的看看网络是如何传输数据包的。从 ClientHello 开始。

从 TLS 1.2 Record Layer 的 Length 字段中我们可以看到 TLS 记录层的这条 TLS 握手消息长度是 512 字节,其中 ClientHello 消息中占 508 字节。ClientHello 中标识了 Client 最高支持的 TLS 版本是 TLS 1.2 (0x0303)。Client 支持的密码套件有 17 种,优先支持的是 TLS_AES_128_GCM_SHA256 。Session ID 的长度是 32 字节,这里不为空。压缩算法是 null。signature_algorithms 中标识了 Client 支持 9 对数字签名算法。

默认情况下 TLS 压缩都是关闭的,因为 CRIME 攻击会利用 TLS 压缩恢复加密认证 cookie,实现会话劫持,而且一般配置 gzip 等内容压缩后再压缩 TLS 分片效益不大又额外占用资源,所以一般都关闭 TLS 压缩。

ClientHello 中发送了 status_request 扩展,查询 OCSP 封套消信息。发送了 signed_certificate_timestamp 扩展,查询 SCT 信息。发送了 application_layer_protocol_negotiation (ALPN)扩展,询问服务端是否支持 HTTP/2 协议。supported_group 扩展里面标识了 Client 中支持的椭圆曲线。SessionTicket TLS 扩展表明了 Client 支持基于 Session Ticket 的会话恢复。

再看看 ServerHello 消息。

从 TLS 1.2 Record Layer 的 Length 字段中我们可以看到 TLS 记录层的这条 TLS 握手协议消息长度是 82 字节,其中 ServerHello 消息中占 78 字节。Server 选择用 TLS 1.2 版本与 Client 进行接下来的握手流程。Server 与 Client 协商出来的密码套件是 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384。

Server 支持 HTTP/2,在 ALPN 扩展中进行了回复。

从 TLS 1.2 Record Layer 的 Length 字段中我们可以看到 TLS 记录层的这条 TLS 握手消息长度是 2544 字节,其中 Certificate 消息中占 2540 字节,Certificates 证书链包含 2 张证书,Server 实体证书 1357 字节,中间证书 1174 字节。中间证书是 Let's Encrypt 签发的。两张证书都是用 sha256WithRSAEncryption 签名算法进行签名的。

从 TLS 1.2 Record Layer 的 Length 字段中我们可以看到 TLS 记录层的这条 TLS 握手协议消息长度是 535 字节,其中 Certificate Status 消息中占 531 字节。Server 将 OCSP 的 response 发送给 Client。

从 TLS 1.2 Record Layer 的 Length 字段中我们可以看到 TLS 记录层的这条 TLS 握手协议消息长度是 116 字节,其中 ServerKeyExchange 消息中占 112 字节。由于协商出来的是 ECDHE 密钥协商算法,所以 Server 需要把 ECDH 的参数和公钥通过 ServerKeyExchange 消息发给 Client。这里 ECDHE 使用的 ECC 命名曲线是 x25519 。Server 的公钥是 (62761b5……),签名算法是 ECDSA_secp256r1_SHA256 。签名值是 (3046022……)。

ServerHelloDone 消息结构很简单,见上图。

由于是 ECDHE 协商算法,所以 Client 需要发送 ECC DH 公钥,对应的公钥值是 (1e58cf……)。公钥长度 32 字节。

ChangeCipherSpec 消息结构很简单,发送这条消息是为了告诉 Server ,Client 可以使用 TLS 记录层协议进行密码学保护了。第一条进行密码学保护的消息是 Finished 消息。

Finished 消息结构很简单,见上图。

Server 如果只是 SessionTicket,那么会生成新的 NewSessionTicket 返给 Client,然后同样返回 ChangeCipherSpec 消息和 Finished 消息。

当页面关闭的时候,Server 会给 Client 发送 TLS Alert 消息,这条消息里面的描述就是 Close Notify。同时 Server 会发送 FIN 包开始 4 次挥手。

五. TLS 1.2 会话恢复

Client 和 Server 只要一关闭连接,短时间内再次访问 HTTPS 网站的时候又需要重新连接。新的连接会造成网络延迟,并消耗双方的计算能力。有没有办法能复用之前的 TLS 连接呢?办法是有的,这就涉及到了 TLS 会话复用机制。

当 Client 和 Server 决定继续一个以前的会话或复制一个现存的会话(取代协商新的安全参数)时,消息流如下:

Client 使用需要恢复的当前会话的 ID 发送一个 ClientHello。Server 检查它的会话缓存以进行匹配。如果匹配成功,并且 Server 愿意在指定的会话状态下重建连接,它将会发送一个带有相同会话 ID 值的 ServerHello 消息。这时,Client 和 Server 必须都发送 ChangeCipherSpec 消息并且直接发送 Finished 消息。一旦重建立完成,Client 和 Server 可以开始交换应用层数据(见下面的流程图)。如果一个会话 ID 不匹配,Server 会产生一个新的会话 ID,然后 TLS Client 和 Server 需要进行一次完整的握手。

C

 Client Server ClientHello --------> ServerHello [ChangeCipherSpec]  Application Data  Application Data 

Session ID 由服务器端支持,协议中的标准字段,因此基本所有服务器都支持,服务器端保存会话 ID 以及协商的通信信息,占用服务器资源较多。

1. 基于 Session ID 的会话恢复

当 Client 通过一次完整的握手,与 Server 建立了一次完整的 Session,Server 会记录这次 Session 的信息,以备恢复会话的时候使用:

  • 会话标识符(session identifier):
  • 每个会话的唯一标识符
  • 对端的证书(peer certificate):
  • 对端的证书,一般为空
  • 压缩算法(compression method):
  • 一般不启用
  • 密码套件(cipher spec):
  • Client 和 Server 协商共同协商出来的密码套件
  • 主密钥(master secret):
  • 每个会话都会保存一份主密钥,注意不是预备主密钥。(读者可以想想为什么,如果还是想不通,见 《HTTPS 温故知新(五) —— TLS 中的密钥计算》)
  • 会话可恢复标识(is resumable):
  • 标识会话是否可恢复

当 Server 保存了以上的信息,可以再次计算出 TLS 记录层需要的 security parameters 加密参数,从而加密应用数据。

基于 Session ID 会话恢复的流程如下:

 Client Server ClientHello --------> ServerHello [ChangeCipherSpec]  Application Data  Application Data 

Client 发现请求的网站是之前请求过的,即内存中存在 Session ID,那么再次建立连接的时候会在 ClientHello 中附带与网站对应的 Session ID。Server 的内存中会保存一份 Session Cache 的字典,key 是 Session ID,value 是会话信息。Server 收到 ClientHello 以后,根据传过来的 Session ID 查看是否有相关的会话信息,如果有,就会允许 Client 进行会话恢复,直接发送 ChangeCipherSpec 和 Finished 消息。如果没有相关的会话信息,就会开始一次完整的握手,并在 ServerHello 中生成新的 Session ID 返回给 Client。Client 收到 Server 发来的 ChangeCipherSpec 和 Finished 消息,代表会话恢复成功,也发送 ChangeCipherSpec 和 Finished 消息作为回应。

rsa前后端加密流程_HTTPS 温故知新(三)——直观感受 TLS 握手流程(中)相关推荐

  1. rsa前后端加密流程_不懂前后端分离?这篇就够了

    一 传统的开发模式 前后端分离前我们的开发协作模式一般是这样的: 前端写好静态的HTML页面交付给后端开发.静态页面可以本地开发,也无需考虑业务逻辑只需要实现View即可. 后端使用模板引擎去套模板, ...

  2. Rsa前后端加密交互 带demo

    介绍就不说了...大家找过来就懂,不懂可以留言探讨 已经实现前后端交互了 前端公钥加密 使用的第三方js:jsrsasign-all-min.js 前端使用公钥加密.后端私钥解密 后端私钥签名.前端公 ...

  3. aes 加密_结合RSA与AES实现前后端加密通信

    结合RSA与AES实现前后端加密通信 一.思路 使用RSA秘钥生成工具生成一对公钥(A)和私钥(B),前端保留A,后端保留B. 前端发送数据时,先生成一串随机16位字符串作为AES的秘钥(C),然后使 ...

  4. AES前后端加密解密

    AES前后端加密 关于AES-来自百度百科 后端代码 前端代码 关于AES-来自百度百科 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称R ...

  5. 前后端分离的探索(三)

    文桥,13级机械系学生.在LSGO软件技术团队负责前端部分,本图文是介绍目前流行的前后端分离技术的第三篇,希望大家能够对这块有所了解. 当我们培养了对一门技术的认知,并通过一系列项目对这门技术进行了打 ...

  6. Vue前端和Java后端 联调使用AES 前后端加密解密

    Vue前端和Java后端 联调使用AES 前后端加密解密 最近在项目中需要针对重要数据进行加密传输,在网上找了一大推加密方式 最终采用AES 加密 Java端 package com.zk.web.u ...

  7. AES和RSA前后端加解密

    先了解AES和RSA加密算法 AES算法 1.运算速度快,在有反馈模式.无反馈模式的软硬件中,Rijndael都表现出非常好的性能. 2.对内存的需求非常低,适合于受限环境. 3.Rijndael 是 ...

  8. sm4 前后端 加密_这7个开源的Spring Boot前后端分离项目整理给你

    来源|公众号:江南一点雨 前后端分离已经开始逐渐走进各公司的技术栈,不少公司都已经切换到前后端分离开发技术栈上面了,因此建议技术人学习前后端分离开发以提升自身优势.同时,也整理了 7 个开源的 Spr ...

  9. 前后端分别部署教程 ---- 第三部分项目部署和挂载到微信公众号

    3. 前端 这里介绍的是idea开发工具下的项目打包 3.1 项目打包 一定要在指定项目路径下打开 Terminal,不然会打错项目的包. 右击项目名称,然后点击 Open in Terminal: ...

最新文章

  1. java getitemcount_RecyclerView.Adapter中的getItemCount() 返回数组的size是出现异常?
  2. keras从入门到放弃(六)多层感知器(神经网络)
  3. swift 原生给h5发消息_Swift-WKWebView与JavaScript的细节,H5页面跳转原生界面
  4. background图片不显示_一种解决Retina屏幕1px边框显示问题的方案
  5. [11] ADB 实用功能
  6. 如何双击就以管理员身份运行批处理
  7. 收藏精美网页设计作品的200佳网站推荐(系列五)
  8. 音频系统测试软件:Smaart for Mac
  9. 夺旗赛 CTF 六大方向基础工具简介集合(MISC,WEB,Crypto,Reverse,Pwn,Mobile)
  10. Spring JDK动态代理详解
  11. mysql 5.7 64位 解压版安装
  12. Excel——从文本中提取数字
  13. 双11,一大波建站优惠,你还不来网站建设吗?
  14. 2019-2-14SQLserver中拼音查询数据
  15. 简单三招,教你做个app
  16. Denoising point sets via L0 minimization
  17. 第一代程序员王小波 (送书活动)
  18. 电源设计中最常见的四种滤波电路原理及特点解析
  19. python scrapy 爬取妹子图的照片
  20. 矩阵的创建和计算方法

热门文章

  1. 如何从Project数据库中读取mpp文件中自定义域以及自定义大纲代码
  2. 华为计算机品牌及型号怎么查,华为电脑怎么看型号
  3. 高通开发系列 - network之移动网络拨号失败和netmgrd服务分析
  4. pyhton 对列表按照日期进行排序
  5. LeetCode 648. 单词替换
  6. 视觉灵感:30个漂亮的的网站设计
  7. MaskFormer 在 MMDtection 中复现全流程解析
  8. python英汉互译-中汉英在线翻译
  9. Idea import导包去掉*
  10. 对ASM存储管理的一些初步理解记录