winshark 筛选条件为:tls and ip.src==xxx

本文通过对一次 TLS 握手过程的数据抓包分析做为切入点,希望能进一步的帮助大家理解 HTTPS 原理。

HTTPS 是建立在 SSL/TLS 传输层安全协议之上的一种 HTTP 协议,相当于 HTTPS = HTTP + SSL/TLS。第一篇文章 “HTTPS - 通俗易懂的阐述 HTTPS 协议,解决面试难题” 更多是理论上的一些阐述,能解决一些面试及常见问题,例如 “SSL/TLS” 的关系是什么?文中都有介绍。本文通过对一次 TLS 握手过程的数据抓包分析做为切入点,希望能进一步的帮助大家理解 HTTPS 原理。

TLS 协议

TLS 是一种密码学协议,保证了两个端点之间的会话安全,一种最好的学习方法是使用抓包工具,捕获网络数据包,基于这些真实的数据包能够有一些直观的感受,例如:Wireshark,它可以捕获 HTTP、TCP、TLS 等各种网络协议数据包,是我们学习的好工具。

TLS 定义了四个核心子协议:握手协议 (handshake protocol)、密钥规格变更协议 (change cipher spec protocol)、应用数据协议 (application data protocol) 和警报协议 (alert protocol),这里最主要、最复杂是“握手协议”,协商对称密码就是在该协议中完成的。

来源:https://hpbn.co/assets/diagrams/9873c7441be06e0b53a006aac442696c.svg

握手过程图示

参考 “网络协议那些事儿 - 如何抓包并破解 HTTPS 加密数据?”,本文是抓取的 www.imooc.com 网站数据包,基于 TLS v1.2 协议未对数据包做解密处理。

下图展示了 HTTPS 链接建立、TLS 握手协议里参数传递、证书验证、协商对称密钥的过程,更详细的内容,下文会介绍。

tls-1-2-full-handshake.jpg

握手协议

握手协议是 TLS 协议中最复杂的一部分,在这个过程中双方会协商链接参数(TLS 版本号、随机数等)并完成身份验证。里面可能会存在几种情况:完整握手,对服务器进行身份验证、恢复之前的会话采用的简短握手、对客户端和服务器都进行身份验证握手,下文以完整握手为例。

在建立 TCP 链接之后,每一个 TLS 链接都会以握手协议开始,完整握手是客户端与服务器之前未建立会话,在第一次会话时会经历一次完整的握手。

Client Hello

在一次新的握手协议中,客户端(浏览器)首先发出的一条消息是 “Client Hello”,告诉服务器我将给你传递这些数据:

  • Version:客户端支持的最佳协议版本号。
  • Random:客户端提供给服务器的随机数,在每次握手中都会重新生成,这个随机数用于后续生成密钥。
  • Session ID:会话 ID 在第一次链接时该字段是空的,表示客户端并不希望恢复某个已存在的会话。
  • Cipher Suites:客户端所支持的所有秘密套件,按优先级顺序排列。
复制

Handshake Protocol: Client Hello 
  Handshake Type: Client Hello (1) 
  Length: 223 
  Version: TLS 1.2 (0x0303) 
  Random: b0fcb3aca27c6de8b0e4f146b92d33f24e6a671e62f8f6f669aabbfc19bb4326 
  Session ID Length: 0 
  Cipher Suites Length: 92 
  Cipher Suites (46 suites) 
    Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030) 
    Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c) 
    Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xc028) 
    ... 

Server Hello

“Server Hello” 是服务器在收到客户端 “Client Hello” 之后的一个回应,告诉客户端服务器的协议版本、服务器也会给出一个随机数 Random 用于后续生成密钥,Cipher Suite 是从客户端 “Client Hello” 消息的 Cipher Suites 里选择的一个密码套件。

复制

Handshake Protocol: Server Hello 
    Handshake Type: Server Hello (2) 
    Length: 89 
    Version: TLS 1.2 (0x0303) 
    Random: 616d836f609800aaa1713462f61d50cc6472c45b54c0ac58dd52b9db4d555f6f 
    Session ID Length: 32 
    Session ID: 279fb99351526e29a4ce41af4cbff5575933e5c45dff7a2016a16cdf414f22c2 
    Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f) 

了解密码套件构成

Certificate, Server Key Exchange, Server Hello Done

在 “Server Hello” 之后,服务器紧跟随着发出 “Certificate, Server Key Exchange, Server Hello Done” 这三个消息告知客户端。

Certificate(发送服务器证书信息到客户端)

证书信息,典型的 Certificate 消息用于携带服务器 X.509 证书链,一个接一个组合而成,主证书第一个,之后中间证书和根证书,服务器的公钥也包含在证书信息中。

复制

Handshake Protocol: Certificate 
    Handshake Type: Certificate (11) 
    Length: 2781 
    Certificates Length: 2778 
    Certificates (2778 bytes) 
        Certificate Length: 1407 
        Certificate: 3082057b30820463a0030201020210040f1f824b17ca53814dc5c6f4c6a0a8300d06092a… (id-at-commonName=*.imooc.com) 
        Certificate Length: 1365 
        Certificate: 3082055130820439a003020102021007983603ade39908219ca00c27bc8a6c300d06092a… (id-at-commonName=RapidSSL TLS DV RSA Mixed SHA256 2020 CA-1,id-at-organizationName=DigiCert Inc,id-at-countryName=US) 

这个证书链在浏览器地址栏点击域名前面的 “小锁”,可看到如下信息,最上面是根证书、中间(RapidSSL)是中级证书颁发机构、*.imooc.com 这个是 CA 颁发给我们的域名证书。

Server Key Exchange(密钥交换)

“Server Key Exchange” 消息是携带密钥交换算法需要的额外数据,目的是计算主密钥需要的另一个值:“预主密钥(premaster secret)”。

不同的算法套件对应的消息内容也是不同的,下面 EC Diffie-Hellman(简称 ECDHE)就是密钥交换算法,这个对应 “Server Hello” 消息中选择的密码套件 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 中的 ECDHE。

下面 Server Params 中的 Curve Type 表示曲线类型,本次选中的椭圆曲线名称为 named_curve:secp256r1,再确定基点 G,此时还会选择生成一个随机数做为服务端椭圆曲线的私钥,存放到本地,再根据基点 G 和椭圆曲线的私钥计算出椭圆曲线公钥(这里的椭圆曲线公/私钥都是临时的,只对本次链接生效),名字为 Pubkey 传递给客户端。

为了确保椭圆曲线公钥信息不被篡改,将 Server Params 与客户端和服务器随机值连在一起使用私钥签名,客户端从证书中获得服务器的公钥,就可验证是否来自服务器。客户端和服务器的随机值对于一次握手是唯一的,这也意味着攻击者无法重复利用该签名。

复制

Handshake Protocol: Server Key Exchange 
    Handshake Type: Server Key Exchange (12) 
    Length: 329 
    EC Diffie-Hellman Server Params 
        Curve Type: named_curve (0x03) 
        Named Curve: secp256r1 (0x0017) 
        Pubkey Length: 65 
        Pubkey: 049c1c4eaa2ab8ae7b54482efc5d07e2b191174d804d660be07ded253c86f9bc5cd24f34… 
        Signature Algorithm: rsa_pkcs1_sha512 (0x0601) 
            Signature Hash Algorithm Hash: SHA512 (6) 
            Signature Hash Algorithm Signature: RSA (1) 
        Signature Length: 256 
        Signature: 5b9b1a750f0168f0a57852b4a77c14c351c5b97d7eb4a470fa8e3cf9e385cf7ac16f056f… 

不同的密钥交换算法,生成预主密钥的方式也不同,我们这里的示例以 ECDHE 为主,还有一种密钥交换算法是 RSA,它的密钥交换过程很简单,由客户端生成预主密钥,为 46 字节的随机数,使用服务器的公钥加密,经过“Client Key Exchange” 消息发送到服务端,服务端再用私钥就可解密出这个预主密钥。

基于 RSA 的密钥交换算法被认为存在严重的漏洞威胁,任何能够接触到私钥的人(例如,由于政治、贿赂、强行进入等)都可恢复预主密钥,进而构建相同的主密钥,最终密钥泄漏就可解密之前记录的所有流量了。这种密钥交换算法正在被支持前向保密保密的其它算法替代,例如,我们示例中的 ECDHE 算法在密钥交换时,每个链接使用的主密钥相互独立,如果出现问题也只是影响到当前会话,不能用于追溯解密任何其它的流量。

Server Hello Done

“Server Hello Done” 表示服务器已将握手消息需要的数据都发送完毕。之后就是等待客户端的回应。

复制

Handshake Protocol: Server Hello Done 
    Handshake Type: Server Hello Done (14) 
    Length: 0 

Client Key Exchange(客户端发送给服务器的密钥交换信息)

“Client Key Exchange” 的消息也是携带密钥交换需要的额外数据,不过这一次是客户端发送给服务端的,Client Params 里面提供了客户端生成的临时椭圆曲线公钥信息。

复制

Handshake Protocol: Client Key Exchange 
    Handshake Type: Client Key Exchange (16) 
    Length: 66 
    EC Diffie-Hellman Client Params 
        Pubkey Length: 65 
        Pubkey: 04c64110c2838d112d8fbc8a85a2c2b3b596e70d6ff9198330801df93ce9737432eeabe6… 

客户端验证证书和计算密钥

现在一次 TCP 往返结束了,客户端拿到了服务器的证书、Server Random、Server Params,现在客户端需要验证证书合法性和计算一些加密信息。

验证服务器发来的证书合法性

客户端收到服务器的响应信息,验证证书的合法性,可回顾上一节 深入浅出 HTTPS 原理篇。如果证书校验通过继续往下走。

计算预主密钥

上面也提了,在 “Server Key Exchange” 消息中,服务器对 Server Params 用私钥做了签名,客户端要从证书中获得服务器公钥,验证参数是否来自期望的服务器,这也是身份验证。

身份验证成功之后,得到 Server Params 参数,而 Server Params 参数里包含了 “服务器密钥交换消息” 中生成的临时公钥、secp256r1 椭圆曲线算法,现在客户端使用 secp256r1 算法用这个临时公钥和客户端自己生成的临时私钥相乘计算出预主密钥(premaster secret)。

计算主密钥

现在客户端手里已经有了 Client Random、Server Random、Premaster Secret 三个随机参数,调用 PRF 伪随机函数函数生成 48 字节(384 位)主密钥。

复制

master_secret = PRF(pre_master_secret, "master secret", 
ClientHello.random + ServerHello.random) 

构建会话密钥

上面的主密钥并不是最终的会话密钥,最终的会话密钥使用 PRF 伪随机函数传入主密钥、客户端随机数、服务端随机数生成。

复制

key_block = PRF(master_secret, "key expansion", server_random + client_random) 

这个最终的会话密钥包括:对称加密密钥(symmetric key)、消息认证码密钥(mac key)、初始化项量(iv key,只在必要时生成)。

客户端发出 Change Cipher Spec, Encrypted Handshake Message

当客户端完成密钥计算操作后,还要给服务器发送切换加密模式、验证会话密码消息。

Change Cipher Spec

“Change Cipher Spec” 消息表示客户端已生成加密密钥,并切换到加密模式。

复制

TLSv1.2 Record Layer: Change Cipher Spec Protocol: Change Cipher Spec 
    Content Type: Change Cipher Spec (20) 
    Version: TLS 1.2 (0x0303) 
    Length: 1 
    Change Cipher Spec Message 

注意:“Change Cipher Spec” 不属于握手协议,它是另一种密钥规格变更协议。

Encrypted Handshake Message

这个是将之前所有的握手数据做一个摘要,再用最后协商好的对称加密算法对数据做加密,通过 “Encrypted Handshake Message” 消息发送到服务器进行校验,这个对称加密密钥是否成功。

复制

TLSv1.2 Record Layer: Handshake Protocol: Encrypted Handshake Message 
    Content Type: Handshake (22) 
    Version: TLS 1.2 (0x0303) 
    Length: 60 
    Handshake Protocol: Encrypted Handshake Message 

服务器计算密钥

服务器在收到客户端 “Client Key Exchange” 消息后,这时可以拿到 Client Random、Server Random、Client Params,先计算出预主密钥后,再分别计算出主密钥和最终的会话密钥,这块可参考客户端计算密钥一样的。

服务器发出 Change Cipher Spec, Encrypted Handshake Message

Change Cipher Spec

服务器发出 “Change Cipher Spec” 消息告诉客户端,服务端已生成密钥,请求客户端切换加密模式。

复制

TLSv1.2 Record Layer: Change Cipher Spec Protocol: Change Cipher Spec 
    Content Type: Change Cipher Spec (20) 
    Version: TLS 1.2 (0x0303) 
    Length: 1 

Encrypted Handshake Message

“Encrypted Handshake Message” 这条消息也是服务器对握手的所有数据用协商好的对称加密算法加密,供客户端校验。

如果对抓取后的报文做解密,这里看到的是 “Finished” 消息。

复制

TLSv1.2 Record Layer: Handshake Protocol: Encrypted Handshake Message 
    Content Type: Handshake (22) 
    Version: TLS 1.2 (0x0303) 
    Length: 40 
    Handshake Protocol: Encrypted Handshake Message 

应用数据协议

整个握手过程完毕之后,我们会看到应用数据协议 “Application Data Protocol: http-over-tls”,之后我们的客户端/服务端建立一个安全通信隧道,就可以发送应用程序数据了。

复制

TLSv1.2 Record Layer: Application Data Protocol: http-over-tls 
    Content Type: Application Data (23) 
    Version: TLS 1.2 (0x0303) 
    Length: 101 
    Encrypted Application Data: 1303136ee3f0e6daf0cb0e82d07fcca423c9cb2a26b29e332cdc604397f43c377df9805e… 
    [Application Data Protocol: http-over-tls] 

Reference

https://hpbn.co/transport-layer-security-tls/

HTTPS 权威指南

https://tls.ulfheim.net/

https://datatracker.ietf.org/doc/html/rfc5246

HTTPS - 揭秘 TLS 1.2 协议完整握手过程--此文为转发文,一定要结合wirshark工具看,很清楚的更多相关文章

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

    HTTPS 详解一:附带最精美详尽的 HTTPS 原理图 HTTPS详解二:SSL / TLS 工作原理和详细握手过程 在上篇文章HTTPS详解一中,我已经为大家介绍了 HTTPS 的详细原理和通信流 ...

  2. SSL协议的握手过程

    SSL握手的目的 第一,客户端与服务器需要就一组用于保护数据的算法达成一致. 第二,它们需要确立一组由那些算法所使用的加密密钥. 第三,握手还可以选择对客户端进行认证. SSL 握手概述 SSL 握手 ...

  3. [转帖]IP /TCP协议及握手过程和数据包格式中级详解

    IP /TCP协议及握手过程和数据包格式中级详解 https://www.toutiao.com/a6665292902458982926/ 写的挺好的 其实 一直没闹明白 网络好 广播地址 还有 网 ...

  4. HTTPS 中双向认证SSL 协议的具体过程

    HTTPS 中双向认证SSL 协议的具体过程: 这里总结为详细的步骤: ① 浏览器发送一个连接请求给安全服务器.② 服务器将自己的证书,以及同证书相关的信息发送给客户浏览器.③ 客户浏览器检查服务器送 ...

  5. SSL协议的握手过程(摘录)

    SSL协议的握手过程 为了便于更好的认识和理解 SSL 协议,这里着重介绍 SSL 协议的握手协议.SSL 协议既用到了公钥加密技术(非对称加密)又用到了对称加密技术,SSL对传输内容的加密是采用的对 ...

  6. 为什么用抓包工具看HTTPS包是明文的

    测试或者开发调试的过程中,经常会进行抓包分析,并且装上抓包工具的证书就能抓取 HTTPS 的数据包并显示.由此就产生了一个疑问,为什么抓包工具装上证书后就能抓到 HTTPS 的包并显示呢?不是说 HT ...

  7. SSL 握手过程

    SSL协议的握手过程 SSL 协议既用到了公钥加密技术又用到了对称加密技术,对称加密技术虽然比公钥加密技术的速度快,可是公钥加密技术提供了更好的身份认证技术.SSL 的握手协议非常有效的让客户和服务器 ...

  8. Windows IIS 服务器配置HTTPS启用TLS协议。

    好消息, 程序员专用早餐机.和掌柜说 ideaam,可以节省20元. 点击链接   或復·制这段描述¥k3MbbVKccMU¥后到淘♂寳♀ Windows IIS 服务器配置HTTPS启用TLS协议. ...

  9. HTTPS SSL/TLS协议

    要说清楚 HTTPS 协议的实现原理,至少需要如下几个背景知识.1. 大致了解几个基本术语(HTTPS.SSL.TLS)的含义2. 大致了解 HTTP 和 TCP 的关系(尤其是“短连接”VS“长连接 ...

  10. HTTPS协议,SSL协议及完整交互过程

    文章转自 https://blog.csdn.net/dfsaggsd/article/details/50910999 SSL 1.        安全套接字(Secure Socket Layer ...

随机推荐

  1. java基础学习:java中的反射

    一.什么是java反射 什么是 java 的反射? 说到反射,写这篇文章时,我突然想到了人的"反省",反省是什么?吾一日三省吾身,一般就是反思自身,今天做了哪些对或错的事情. ja ...

  2. 集成 Redis & 异步任务 - SpringBoot 2.7 .2实战基础

    SpringBoot 2.7 .2实战基础 - 09 - 集成 Redis & 异步任务 1 集成Redis <docker 安装 MySQL 和 Redis>一文已介绍如何在 D ...

  3. K8S name_namespace

    Name 由于K8S内部,使用"资源"来定义每一种逻辑概念(功能),故没种"资源",都应该有自己的"名称" "资源"有 ...

  4. Spark 读取HDFS csv文件并写入hive

    package com.grady import org.apache.spark.SparkConf import org.apache.spark.sql.{Row, SaveMode, Spar ...

  5. 基于.NET6的简单三层管理系统

    前言 笔者前段时间搬砖的时候,有了一个偷懒的想法:如果开发的时候,简单的CURD可以由代码生成器完成,相应的实体.服务都不需要再做额外的注册,这样开发人员可以省了很多事. 于是就开了这个项目,期望实现 ...

  6. 腾讯云即时通信 IM 服务 实例项目

    腾讯云即时通信 IM 服务  https://github.com/tencentyun/TIMSDK

  7. 14. 第十三篇 二进制安装kube-proxy

    文章转载自:https://mp.weixin.qq.com/s?__biz=MzI1MDgwNzQ1MQ==&mid=2247484231&idx=1&sn=9e722bee ...

  8. Linux服务器上MinIO生产部署的内核调优

    #!/bin/bash cat > sysctl.conf <<EOF # maximum number of open files/file descriptors fs.file ...

  9. 还不会Traefik?看这篇文章就够了!

    文章转载自:https://mp.weixin.qq.com/s/ImZG0XANFOYsk9InOjQPVA 提到Traefik,有些人可能并不熟悉,但是提到Nginx,应该都耳熟能详. 暂且我们把 ...

  10. AlertManager企业微信报警,时间是UTC时间,错8个小时的两种解决办法

    第一种 {{ (.StartsAt.Add 28800e9).Format "2020-01-02 15:04:05" }} 或者是 {{ ($alert.StartsAt.Add ...