HTTPS协议、编码、交互流程以及SSL介绍

1、概要

HTTPS实际就是:HTTP + SSL,数据连接先进行 SSL 认证通过后,即可将按 HTTP 协议封装后的数据,通过 SSL加密后再经过TCP进行传输,分层结构如下:

HTTP
↓
SSL/TLS
↓
TCP
↓
IP
↓
DLL数据链路层
↓
PL物理层

HTTP 属于应用层协议,要了解 HTTPS,就得先了解什么是 HTTP,再了解 SSL 是如何进行加密验证的。

2、HTTP介绍

名词解释

HTTP全名为Hyper Text Transfer Protocol(超文本传输协议),浏览器服务器相关的web应用,都是采用该协议进行通讯。在诞生初期,它只能传输文本文件,不过现在可以传输文本、图片、音频、视频等任意超文本数据了,最新的版本已经到 HTTP/3,但本文主讲 HTTP/1.1 ,毕竟 1.1 是当前环境下使用最广泛的版本。

HTTP 协议与传统的 TCP 协议(国四/六、808 等二进制协议)相比,会更易于阅读,主要就是因为采用了 ASCII 字符编码,数据都以字母和符号等形式呈现。HTTP 遵循客户端-服务器模型,需要客户端主动向服务器请求,服务器才会响应数据。而一般的 TCP 协议,服务器可以主动给客户端下发命令(HTTP 直到 2 的版本才支持)。HTTP 协议要符合一定的规范,但是它的自由度很高,可以自定义很多协议,所以它的应用场景很广泛。

下面举个从服务器请求一个数据的例子,比如从 www.example.com 获取一份数据,可以直接将以下字符打包,然后通过socket发送即可获取:

GET / HTTP/1.1           - 使用1.1的协议,通过GET方法去获取服务器首页的内容
Host: www.example.com    - 指明了服务器的域名
User-Agent: MyCProgram/1.0
Accept: */*
Connection: close

代码举例

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>

#define MAX_LINE 1024
#define SERVER "www.example.com"
#define PORT 80

int main() {
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0) {
        perror("Failed to create socket");
        return -1;
    }

    struct addrinfo hints, *result;
    int ret;

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    // 域名解析
    if ((ret = getaddrinfo(SERVER, NULL, &hints, &result)) != 0) {
        fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(ret));
        return -1;
    }

    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(PORT);

    // 获取第一个有效的IPv4地址
    struct sockaddr_in *ipv4_addr = (struct sockaddr_in*)result->ai_addr;
    server_addr.sin_addr.s_addr = ipv4_addr->sin_addr.s_addr;
    freeaddrinfo(result); // 释放结果集

    // 连接服务器
    if (connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        perror("Failed to connect");
        return -1;
    }

    // 组建HTTP GET报文
    char request[MAX_LINE] = {0};
    snprintf(request, sizeof(request),
             "GET / HTTP/1.1\r\n"
             "Host: %s\r\n"
             "User-Agent: MyCProgram/1.0\r\n"
             "Accept: */*\r\n"
             "Connection: close\r\n\r\n",
             SERVER);

    // 发送GET请求
    if (send(sock, request, strlen(request), 0) < 0) {
        perror("Failed to send request");
        return -1;
    }
    printf("Sending...\r\n%s", request);

    // 接收响应数据(此处仅做简单处理,实际应用可能需要解析HTTP头和正文)
    
    printf("Receiving...\r\n");
    char response[MAX_LINE];
    while (recv(sock, response, MAX_LINE - 1, 0) > 0) {
        response[MAX_LINE - 1] = '\0'; // 添加终止符防止printf越界
        printf("%s", response);
    }

    // 关闭套接字
    close(sock);

    return 0;
}

运行结果

Sending...
GET / HTTP/1.1
Host: www.example.com
User-Agent: MyCProgram/1.0
Accept: */*
Connection: close

Receiving...
HTTP/1.1 200 OK
Age: 78151
Cache-Control: max-age=604800
Content-Type: text/html; charset=UTF-8
Date: Tue, 16 Apr 2024 07:43:08 GMT
Etag: "3147526947+ident"
Expires: Tue, 23 Apr 2024 07:43:08 GMT
Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
Server: ECS (sac/2520)
Vary: Accept-Encoding
X-Cache: HIT
Content-Length: 1256
Connection: close

<!doctype html>
<html>
<head>
    <title>Example Domain</title>

    <meta charset="utf-8" />
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style type="text/css">
    body {
        background-color: #f0f0f2;
        margin: 0;
        padding: 0;
        font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
        
    }
    div {
        width: 600px;
        margin: 5em auto;
        padding: 2em;
        background-color: #fdfdff;
        border-radius: 0.5em;
        box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
    }
    a:link, a:visited {
        color: #38488f;
        text-decoration: none;
    }
    @media (max-width: 700px) {
        div {
            margin: 0 auto;
            width: auto;
        }
    }
    </style>    
</head>

<body>
<div>
    <h1>Example Domain</h1>
    <p>This domain is for use in illustrative examples in documents. You may use this
    domain in literature without prior coordination or asking for permission.</p>
    <p><a href="https://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>
ale=1" />
    <style type="text/css">
    body {
        background-color: #f0f0f2;
        margin: 0;
        padding: 0;
        font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
        
    }
    div {
        width: 600px;
        margin: 5em auto;
        padding: 2em;
        background-color: #fdfdff;
        border-radius: 0.5em;

浏览器中展现

在浏览器中直接打开这个网址,也是类似于发送 GET 请求,然后浏览器收到数据后再进行渲染,效果如下:
在这里插入图片描述

历史发展

1989 年,任职于欧洲核子研究中心(CERN)的蒂姆·伯纳斯 - 李(Tim Berners-Lee)发表了一篇论文,提出了在互联网上构建超链接文档系统的构想。这篇论文中他确立了三项关键技术。

  • URI:即统一资源标识符,是指一个资源在互联网上的唯一身份标识,它可以分为 URL 和 URN,URL 不仅可以指明资源的位置,还能提供具体的访问方法如 http 或 ftp,类似于一个人的通讯地址,URN 更类似于一个人的身份证号,具有唯一性);
  • HTML:即超文本标记语言,可以描述超文本文档,用来告诉浏览器如何展示网页内容;
  • HTTP:即超文本传输协议,用来传输超文本,比如服务器通过 HTTP 协议传输 HTML 文档。

基于这三项技术,就可以把超文本系统完美地运行在互联网上,让各地的人们能够自由地共享信息,蒂姆把这个系统称为“万维网”(World Wide Web),也就是很多网站前面带的三个 'w'

第一个版本:HTTP/0.9

这个版本的协议,只支持 HTML 文档的传输,主要由于那个年代的互联网非常简陋,计算机处理能力也低,网络上绝大多数的资源都是纯文本,很多通信协议也都使用纯文本,所以 HTTP 的设计也不可避免地受到了时代的限制。

这个版本的数据连接,在收到在服务器响应之后就需要立即关闭连接了,功能非常有限。它发送的报文和响应的报文大致如下:

GET /index.html
<html>
<head><title>Example Page</title></head>
<body>Welcome to the Example Website!</body>
</html>

HTTP/0.9 虽然很简单,但它作为一个“原型”,充分验证了 Web 服务的可行性,给后来的扩展带来了可能性。

第二个版本:HTTP/1.0

这个版本是在 1996 年的 5 月发布的,由互联网标准化组织(Internet Engineering Task Force,IETF)基于实际应用中的实现整理而成,版本被命名为HTTP/1.0,并记载于 RFC1945。它在很多方面增强了 0.9 版本,形式上已经和我们现在的 HTTP 差不多了,增强的地方主要包括:

1. 增加了 HEAD、POST 等新方法,可以获取资源信息和往服务器推送数据;
2. 增加了响应状态码,用以标记数据交互时错误的原因;
3. 增加了协议版本号概念;
4. 增加了 HTTP Header(首部)的概念,让 HTTP 处理请求和响应更加灵活;
5. 传输的数据不再仅限于文本。
第三个版本:HTTP/1.1

1999 年,HTTP/1.1 正式发布, RFC 编号为 2616,该版本被广泛使用至今。1.1 是对 1.0 的小幅度修正,而且随着时间的推移,加上它的优势,1.1 版本就逐渐成为了事实上的行业标准,大多数现代Web服务器和浏览器都遵循 HTTP/1.1 标准。

HTTP/1.1 主要的变更点有:

1. 增加了 PUT、DELETE 等新的方法,可以更新或删除服务器的资源;
2. 增加了缓存管理和控制,支持了断点续传;
3. 明确了连接管理,允许持久连接,之前的版本在连接一次之后就要关闭连接;
4. 允许响应数据分块(chunked),利于传输大文件;
5. 强制要求 Host 头,让互联网主机托管成为可能。

HTTP/1.1 发布的这个时间段,还诞生了许多的知名网站,例如 Google、新浪、搜狐、网易、腾讯等。

后来经过时代的发展,HTTP/1.1 变得愈发庞大和复杂,于是在 2014 年互联网标准化组织对它进行了一次修订,原来的一个大文档被拆分成了六份较小的文档,编号为 7230-7235,它优化了一些细节,但没有实质性的改动。

HTTP/2

HTTP/1.1 发布之后,由于它的一些不足,包括请求-响应模型缺陷、头部巨大且重复、并发连接耗时、服务器不能主动推送等,已经无法满足高速的互联网需求,因此 Google 开发了自己的 SPDY 协议并应用到自家的浏览器 Chrome 以及服务器中,然后随着 Chrome 用户量的增长,Google 借此顺势把 SPDY 推上了标准,最终以 SPDY 为基础的新版本 HTTP/2 协议,在 2015 年发布,RFC 编号为 7540。

HTTP/2 的制定在高度兼容 HTTP/1.1 的同时,在性能方面也做了很大改善,主要的特点有:

1. 增加了二进制分帧层协议(类似于国四国六协议),起始行和首部兼容旧版本的同时,新增了自己的协议结构(头部+数据),把字节和位都用起来了,同时还加入了压缩算法进一步减小数据量;
2. 可发起多个请求,废弃了 1.1 里的管道,原来必须按照请求的顺序去响应数据,现在可以乱序响应,原来比如请求123数据,服务器就得按照123顺序发下来;
3. 使用专用算法压缩头部,减少数据传输量;
4. 允许服务器主动向客户端推送数据;
5. 增强了安全性,默认加密传输,不过没有强制一定要加密。

在这里插入图片描述

HTTP/2 还衍生出了 gRPC 等新协议,但由于 HTTP/1.1 的应用太过广泛,目前它的普及率还比较低,大多数网站使用的仍然还是以前的 HTTP/1.1。

HTTP/3

在 HTTP/2 还处于草案之时,Google 就制定了一个新的协议 QUIC,在 Chrome 和自家服务器里试验,它的主要特点包括:

1. QUIC运行在用户数据报协议(UDP)之上,而不是传统的TCP;
2. 支持连接迁移,意味着当客户端IP地址发生变化(例如,移动设备从Wi-Fi切换到蜂窝网络)时,无需重新建立连接就能继续传输数据;
3. QUIC自带了内置的错误恢复机制,即使个别数据包丢失,也可以迅速恢复,而不像TCP那样需要较长时间的重传超时。

依托 Chrome 庞大的用户和数据量,在 2018 年,互联网标准化组织 IETF 提议将“HTTP over QUIC”更名为“HTTP/3”并获得批准,然后在2022年6月6日正式标准化为RFC 9114。

不过目前只有部分浏览器和云服务商支持该协议,普及率仍旧较低。

2.1 HTTP报文格式

2.1.1 报文组成

HTTP 报文分为发送时的请求报文和接收时的响应报文,二者主要格式都一样,都是由

起始行(start line) + 首部(header) + 空行  +  主体(body,可选) 

组成,每个部分各占一行,每一行(包括空行)的结尾都需要回车换行(有的代码不严谨只有一个换行,但一些服务器或浏览器也兼容)。两种报文的内容形式只有起始行内容不一样,具体如下:

请求报文响应报文
起始行<method> <request-URL> <version>\r\n<version> <status> <reason-phase> \r\n
首部key: value\r\nkey: value\r\n
空行\r\n \r\n
主体<entity-body>\r\n<entity-body>\r\n

起始行-method:访问方法,客户端向服务器发起的对资源执行的操作,包括但不限于以下几种:

GET、HEAD、POST(HTTP1.0) 
OPTIONS、PUT、 DELETE、TRACE和CONNECT(HTTP1.1新增的方法)

GET:从服务器获取一份文件或数据,可以用来获取服务器的首页内容、获取服务器是否有命令下发或从服务器下载文件等,是经常用到的方法。
HEAD:只从服务器获取文件的首部信息,比如可以用来先获取文件的大小或类别,再决定要不要下载。
POST:客户端向服务器发送数据的方法,可以用来进行客户端的状态上报或者上传文件,也是经常用到的方法。
OPTIONS:主要用于获取服务器支持的HTTP请求方法以及其他与资源相关的一些信息。
PUT:主要用途是用于更新或者替换服务器上的某一资源,和POST相比,更倾向于更新服务器的资源。
DELETE:从服务器上删除指定的资源,通常用于删除用户账户、清除数据库记录或者其他类型的资源清理操作。
TRACE:对可能经过代理服务器传送到服务器上去的报文进行追踪,主要用于诊断和调试目的,不用于生产环境。
CONNECT:作用是创建一个从客户端到远程服务器的直接连接通道,比如客户端经过代理服务器直连到远程服务器。

起始行-request-URL:所请求资源的路径,从服务器设置的根路径 ‘/’ 开始,往下可以是’/store/book1’这样的路径。

起始行-version:报文所使用的 http 版本,格式为:HTTP/<major>.<minor>,如当前主流的:HTTP/1.1

首部:提供了关于请求或响应的属性信息,是 HTTP 报文的重点部分。它的格式为键值对形式:关键字:[空格]数据值,一直到空行结束。HTTP 首部字段非常灵活,不仅可以使用标准里的 Host、Connection 等已有的字段,也可以任意添加自定义首部,这就给 HTTP 协议带来了无限的扩展可能,举一些首部的例子:

Content-Type: text/html; charset=UTF-8
Date: Tue, 16 Apr 2024 07:43:08 GMT
Server: ECS (sac/2520)
Content-Length: 1256
Connection: close

// 首部的注意事项
1. 字段名不区分大小写,例如 "Date" 也可以写成 "date",但首字母大写的可读性更好;
2. 字段名里不允许出现空格,可以使用连字符"-",但不能使用下划线"_"。例如,"Content-Length"是合法的字段名,而"Content Length""Content_Length"是不正确的字段名;
3. 字段名后面必须紧接着冒号":",不能有空格,而":"后的字段值前面可以有多个空格,例如"test-header:     test value"4. 字段的顺序没有固定,可以任意排列不影响语义;
5. 字段原则上不能重复,除非这个字段本身的语义允许,例如 Set-Cookie。

主体:entity-body,数据的主体部分,就是实际要发送的数据内容,并不是必须要有的字段,可以是图片、音视频、HTML 文档数据等等。

起始行-status:状态码,即服务器响应的结果状态,主要有以下几类错误码提示:

100~199,一般信息提示
200~299,表示请求成功
300~399,资源已被移走,重定向等
400~499,客户端的请求出错,比如常见的 404,就是服务器找不到对应 URL 的资源,403 就是服务器拒绝请求
500~599,服务器出错

起始行-reason-phase:是对状态码的可读字符描述,比如 OK 或 Not Found 等,直观易懂。

例子

下面举个 HTTP 报文例子进行简要说明,从服务器获取 test.txt 文件:

请求报文:

GET /test.txt HTTP/1.1  -- 起始行,必须要有,第一个参数为HTTP方法,告诉服务器要执行什么动作,第二个为所请求数据的地址,第三个为HTTP协议版本
Host: www.example.com   -- 首部:Host是请求报文必须要有的字段,它表示请求的服务器的域名地址
Accept: */*             -- 首部:通常要有,对传输的数据类型进行协商,这边accept告诉服务器自己接受的消息类型是任意类型,还有其他比如json、text、binary等等
CRLF                    -- 回车换行,必须要带
                        -- 主体部分,GET的请求方式,可以不带主体

响应报文:

HTTP/1.1 404 Not Found              /* 起始行,第一个为HTTP协议版本,第二个为响应码,第三个为响应码的简短解释 */
Date: Thu, 11 Jul 2020 15:33:24 GMT /* 首部,通用首部,这边为消息的时间 */
Content-type: text/plain            /* 首部,实体首部,说明消息主体的属性,可以是application/json或text/plain等 */
Content-length: 0                   /* 表示报文里主体的长度,如果没有这个字段,那么主体就是不定长的,需要使用 chunked 或 range 方式分段传输。 */
CRLF                                /* CRLF 空行 */
...                                 /* 消息主体,如果请求的test.txt存在,那它就通过主体传输过来

对 HTTP 报文的解析和处理实际上主要就是对首部字段的处理,理解了首部字段基本也就理解了 HTTP 报文,下面讲下首部的分类。

报文的首部可以分为 通用首部、请求首部、响应首部、实体首部、扩展首部 等 5 种类型。

通用首部:通用的首部,比如Date日期,请求/响应报文都可以有;
请求首部:出现在请求报文中,比如accept,是对请求报文的细节补充,进一步描述自己的请求;
响应首部:由服务器向客户端返回响应报文中使用的字段,用于补充响应的附加信息、服务器信息等;
主体首部:对主体部分的描述,比如主体长度、编码方式等等;
扩展首部:用户自定义的首部。

除了标准的首部类型,还有诸多自定义的类型,详细可以看 RFC 7230 ~ 7235。

2.1.2 主体格式说明

主体的格式,可以是文本、图片、视频等文件,也可以是二进制数据,它按照 MIME(Multipurpose Internet Mail Extensions,多用途因特网邮件扩展类型)类型标准来定义。

比如要发送图片文件, MIME 中 image/jpeg 表示图片文件,那消息的首部中就需要用 Content-type: 字段来定义说明,常见的有以下几种类型:

Content-type: text/html  /* HTML 格式的文本文档 */
Content-type: text/plain /* 普通的 ASCII 文本文档 */
Content-type: image/jpeg /* JPEG格式的图片 */
Content-type: image/gif  /* GIF格式的图片 */
Content-type: video/quicktime                  /* Apple 的QuickTime 电影 */
Content-type: application/vnd.ms-powerpoint    /* 微软的powerpoint文件 */
Content-type: application/octet-stream         /* 二进制文件,未知的文件格式就选这个 */

//POST方法提交数据的请求方式常用以下几种MIME类型
Content-type: application/x-www-form-urlencoded /* 默认使用 */
Content-type: application/json
Content-type: multipart/form-data               /* 一般用来上传文件 */
...

还有很多其他的 MIME 类型可以看定义原文RFC 2045~2049。

如果传输的文件不大,那可以直接文件元数据放在主体中,发送一次报文就可以了。但是如果文件比较大,那就可以用分块传输编码或压缩编码进行传输,如果不想传输完整的文件或者要断点续传,也可以使用“范围请求”(range requests),即请求某个范围内的数据,如第 100 个到 500 个字节的数据,后面 2.2.4 文件下载 小节会介绍相关数据传输的具体例子。

2.1.3 HTTP编码要求

虽然 HTTP 的编码是整个 ASCII 码的范围,但是一般约定 HTTP 的起始行和头部只取从空格(0x20)到~(波浪线,0x7E)的部分,以及回车(0x0D)和换行(0x0A),因为控制字符(如0x00到0x1F)在HTTP头部中有特殊用途或可能引起解析问题,主体部分没有特别严格的要求。

由此引入了 URL 编码和 BASE64 编码,这两种编码都可以将任意的数据转换成 ASCII 码数据,当 HTTP 报文中的头信息需要包含特殊字符(比如超过 0x7f 的数据)时,这些字符就需要经过 URL 或 BASE64 编码转成小于 0x7f 的 ASCII 码。
在这里插入图片描述

2.2 在嵌入式设备中的应用

2.2.1 数据上传

客户端可以主动使用 POST 方法,对数据进行上传,比如向服务器 example-backend 上传以下国四数据:

23 23 01 43 41 54 30 30 33 31 33 56 48 46 4B 31 30 31 36 37 01 01 00 1C 18 03 05 13 3B 08 00 06 38 39 38 36 30 34 42 35 31 30 32 32 43 31 32 37 33 35 38 38 6C 

发送:

POST /receiver HTTP/1.1                 -- 表示采用1.1的协议发送数据到服务器的/receiver目录
Host: www.example-backend.com           -- 服务器的域名
Accept: */*                             -- 表示接受任意类型数据
Accept-Encoding: gzip,deflate           -- 表示接受的数据可以是gzip或deflate算法压缩的
Content-Type: text/plain                -- 表示要发送的主体数据类型是文本形式,所以原数据需要经过base64编码
Content-length: 72                      -- 表示要发送的主体数据的长度

IyMBQ0FUMDAzMTNWSEZLMTAxNjcBAQAcGAMFEzsIAAY4OTg2MDRCNTEwMjJDMTI3MzU4OGw=  -- 经过base64编码后再发送

响应:

HTTP/1.1 200           -- 表示服务器接收的结果,200为接收成功
Server: nginx          -- 表示服务器的类型
Date: Tue, 05 Mar 2024 11:59:09 GMT -- 表示服务器响应的时间
Content-Length: 0      -- 表示响应数据的长度,如果有需要响应的数据,这里就填充对应的长度
Connection: keep-alive -- 表示允许长连接

...                    -- 如果Content-Length有带长度,这里就填充对应的要响应的数据
2.2.2 命令下发

命令的下发需要客户端主动通过 GET 方法去获取,触发客户端发起请求的方式可以是是短信,定时请求,传感器触发请求等,例子如下:

发送:

GET /configuration HTTP/1.1
Host: www.example.com
Accept: */*                  -- /* 表示接受任意类型数据 */
Accept-Encoding: gzip,deflate

-- 一般不带主体

响应:

 HTTP/1.1 200
Date: Tue, 05 Mar 2024 11:59:07 GMT
Content-Type: application/xml;charset=UTF-8
Content-Length: 16897
Connection: keep-alive

<?xml version="1.0" encoding="UTF-8"?>... -- 比如命令被打包在一个xml文件中,就下发xml文件。也可以是十六进制的数据,但需要在首部Content-Type中声明。
2.2.3 文件上传

HTTP上传文件最常用的是通过 POST 方法进行上传,上传方式主要分为以下几种:

1、multipart/form-data: 表单上传,这是最常见的文件上传方式,适用于大多数场景。在 POST 请求中,文件作为主体的一部分,与其他表单字段一同发送。内容类型即首部的Content-Type 需要设置为 multipart/form-data,并且每个部分(包括文件和其他表单项)由边界字符串分隔。这种方式支持上传多个文件及包含额外的表单字段。

2、application/x-www-form-urlencoded: 虽然主要用于发送键值对形式的数据,但理论上也可以上传文件。然而,因为它会将所有数据编码为URL格式,不适合大文件或二进制数据,因此实际上很少用于文件上传。

3、application/octet-stream: 专门用来上传二进制文件,可以将Content-Type设置为 application/octet-stream。这种方式通常用于直接上传单一的二进制文件,不伴随其他表单数据,且可能需要在请求头中使用 Content-Disposition 来指定文件名。

4、RAW: 在一些API接口中,允许以纯文本、JSON、XML等形式上传文件内容,此时请求体直接包含文件的原始数据,适合特定类型的文本或已知格式的数据上传,但通常不用于常规文件上传场景。

这边以最常用的表单上传为例子,将文件 example. txt 上传到 www.example.com 。首先需要设置首部 Content-Type 的值为 multipart/form-data,同时增加 boundary 字段,即界定符,它可以把数据类型和文件数据分隔开,同时也能根据它的值确定是否文件传输完成,方法就是在它的值后面跟上两个杠 '--',然后放在最后即表示文件传输结束 :

POST /upload HTTP/1.1
Host: www.example.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Length: 333
Accept-Encoding: gzip, deflate
Connection: keep-alive

------WebKitFormBoundary7MA4YWxkTrZu0gW    // 先发送了个表单,可以表明用户的身份
Content-Disposition: form-data; name="user_name"

user_test
------WebKitFormBoundary7MA4YWxkTrZu0gW    // 再发送文件,先描述了文件的名称和类型,再发送文件数据
Content-Disposition: form-data; name="file"; filename="example.txt"
Content-Type: text/plain

This is the content of the example.txt file.
... // 分块连续传输
EOF
------WebKitFormBoundary7MA4YWxkTrZu0gW--
2.2.4 文件下载

HTTP协议中,文件下载通常有以下几种方法:

1、 简单文件下载: 这是最基本的下载方式,客户端发送一个 HTTP GET 请求到服务器,请求指定 URL 的文件。服务器响应这个请求,将文件内容作为响应体返回给客户端。客户端接收到数据后,直接将其保存为文件。这种下载方式适用于比较小的文件。

2、分块下载(Chunked Download): 客户端发起一个 HTTP GET 请求,服务器将文件分割成多个数据块,逐个发送给客户端。客户端就可以有效管理内存使用,避免因文件过大而导致的内存溢出问题,这种方式适合动态生成的内容或未知大小的数据流,如实时日志、视频流等。

3、范围请求(Range Requests): HTTP 协议支持范围请求,允许客户端指定它想要获取的数据内容的一部分。这对于实现断点续传非常有用。如果下载过程中断,客户端可以发送一个新的请求,指定从之前中断的地方继续下载,而不是重新下载整个文件。

简单文件下载

和《2.2.2 命令下发》类似,直接一个 GET 报文下来然后保存整个报文到文件即可。

分块下载

服务器会把报文以块的方式进行传输,同时响应报文中会指定首部 Transfer-Encoding 的值为 chunked,举例:

GET /fota_file.zip HTTP/1.1
Host: www.example.com
Connection: keep-alive

HTTP/1.1 200 OK
Date: Mon, 29 Apr 2024 12:34:56 GMT
Server: Apache/2.4.7 (Ubuntu)
Transfer-Encoding: chunked                                  -- 需要指定为chunked,表示本次是分块下载
Content-Disposition: attachment; filename="fota_file.zip"   -- 建议的文件名
Content-Type: application/zip

// 分块下载,每一块都包含该块的数据长度和内容,格式为[长度]\r\n[数据内容]\r\n

7d0                          // 这里是第一个chunk的大小,以十六进制表示,这边是1968字节
[...第一个数据块的内容...]
0d                           // 这是一个大小为13字节的chunk
[...第二个数据块的内容...]
0                            // 最后一个chunk,大小为0,表示数据传输结束

范围请求下载

需要在请求时,首部增加 Range 字段,明确下载的范围(如果服务器支持的话,可以先用 HEAD 方法获取文件的大小,再用 GET 去下载)举例:

GET /fota_file.zip HTTP/1.1
Host: www.example.com
Accept-Encoding: gzip, deflate
Range: bytes=0-1023                      // 范围请求下载的关键,在这里请求了从第0字节到第1023字节的数据
If-Range: Wed, 21 Oct 2015 07:28:00 GMT  // 可选,如果上次收到过文件的修改时间,这边带上这个时间,服务器就会去对比两个文件时间是否一致,不一致服务器直接会从0开始发送
HTTP/1.1 206 Partial Content                                // 206,表示将会传输请求的部分内容
Date: Mon, 29 Apr 2024 12:34:56 GMT
Server: Apache/2.4.7 (Ubuntu)
Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT
Content-Disposition: attachment; filename="fota_file.zip"   // 建议的附件文件名
Content-Range: bytes 0-1023/1234567                         // 表示返回的部分内容范围及总大小
Content-Length: 1024
Content-Type: application/octet-stream                      // 表示文件原始数据

[...这里是实际的文件数据块内容...]

讲完了 HTTP,接下来讲下 SSL 加密,HTTP 数据本身格式都是不变的,只是套上 SSL 加密,就变成了 HTTPS。

3、SSL与数字证书

3.1 SSL定义

SSL(Secure Sockets Layer,安全套接字层)是一种网络安全协议,设计初衷是为了在互联网上传输数据时,提供安全性和数据完整性保障。它通过在通信双方之间建立一个加密的连接来工作,确保敏感信息如密码、金融交易等在传输过程中不被窃听、篡改或伪造。

HTTP的常用安全措施,包括基本认证、摘要认证和 SSL 加密等。基本认证就是比如采用用户名和密码来认证;摘要认证则是核对双方的密码摘要(比如MD5加密)是否正确。这两个的安全性都不高,现在常用的都是采用 SSL 加密措施。现在的 SSL(Secure Sockets Layer)严格意义上来说应该叫 TLS(Transport Layer Security)传输层安全,TLS 是由 SSL 发展而来的,叫 SSL 只是习惯性叫法。

HTTPS 数据的交互,是先由 SSL 进行双方的验证,通过后再对 HTTP 数据进行加密传输,HTTP 默认的端口是 80,而 HTTPS默认的端口是 443。

3.2 数据加解密原理简介

简单来说,就是数据加密时,明文 P 经过编码一个很难破解的函数 E,通过密钥 e 作为参数,就可以加密成密文C;
在这里插入图片描述

解密时,密文 C 经过另外的解码函数 D,和解码密钥 d,就可以解码还原为明文 P,这边的编码函数 E 和解码函数 D 就是互为反函数。

这种加密和解密采用不同类型的密钥的方式,称之为非对称加密,比如 RSA 算法,如果使用的密钥是一样的即 d = e(如下图),那么则称之为对称加密,比如 AES 算法,两种加密算法的分类可以在 附录二加密算法分类 中了解。
在这里插入图片描述

非对称加密中有两个重要的数据:私钥公钥,可以把它们想象成一把钥匙和一个开了锁的锁头,钥匙只留在一个人的手里,但是可以把锁头给别人,别人用这个锁把重要的数据锁起来,然后再数据发送给拥有钥匙的人,这个人再用唯一的钥匙打开查看,期间其他任何人都无法开锁。

SSL 采用了非对称加密算法先验证完合法身份,建立起安全通道之后,再采用对称加密来进行数据加密通讯,这样不仅能保证安全,也可以提高数据传输效率(非对称加密计算耗时会更长)。下面就先讲下非对称加密中涉及到的几个概念以及如何验证身份。

3.3 私钥和证书认证

SSL 认证时,需要提前生成私钥和证书,同时还有一个可信任的第三方机构 CA 的证书,来对数据传输的双方进行身份的认证,并把私钥和证书部署到服务器或客户端中。

私钥:私钥是通过特定的算法生成的,比如 RSA 、DSA 和 ECC 等,是用来解密公钥加密的信息、生成数字签名的工具,是用户持有的秘密部分,不能泄露。用户生成私钥时通常会同时生成公钥,公钥被包括到证书请求文件中给可信任的证书签发机构 CA(Certificate Authority)作为签名用,CA 签完名就会生成一张证书。

证书:证书是经过权威机构和可信任的机构签名的一份文件,通过证书可以验证要访问的域名是否是真实的可信任的。证书里包含了公钥,同时包含了域名拥有者等各种信息,浏览器在访问网站时,网站需要把证书传给浏览器,浏览器再根据内置的 CA 证书验证证书的合法性。

证书链:CA 机构通常有多级的部门,负责不同的客户,当一个服务器或客户端的证书不是最上级的 CA 签名的,就会在证书中添加多个证书,这个证书可以从服务器证书追溯到最顶级的根证书,一般浏览器内置了顶级的 CA 根证书,浏览器通过根证书去一级一级验证服务器的证书,就能确认其真实性,这样一个包含了多级证书的文件就是证书链,大致结构如下图:
在这里插入图片描述

CA 证书:就是 CA 用自己的私钥给自己签名的证书,可以用来验证 CA 签发的服务端或客户端的证书(链)的合法性,如果包含了根证书以及多级的中间证书,那也就变成了 CA 证书链,与服务器之类的证书链区别就是没有包含服务器的证书。一般客户端只要内置 CA 根证书即可,在 SSL 握手过程中,服务器会将其证书链发送给客户端,客户端会从根证书开始逐级验证每个中间证书的签名和有效性一直到服务器证书。

在双向认证的场景下,服务端和客户端通讯认证时会用到的证书情况:

server:服务端私钥、服务端证书(链)、给客户端签发证书的CA的根证书
client:客户端私钥、客户端证书(链)、给服务端签发证书的CA的根证书

单向认证时,服务端和客户端通讯认证时会用到的证书情况:

server:服务端私钥、服务端证书(链)
client:给服务端签发证书的CA的证书

3.4 CA机构与证书生成

CA 机构

CA机构(Certificate Authority,证书授权中心)是一种权威的第三方信任机构,负责发放、管理以及撤销数字证书。由于 CA 机构严格要求身份验证、遵循国际安全标准、提供透明和可验证的信任机制,同时受到法律的约束,所以很多企业和个人使用 CA 机构进行证书的签发,只要验证了是权威 CA 机构签发的证书,用户就可以认为该证书对应的服务器是安全真实的。

每个 CA 机构都有一个根证书和私钥,任何人都可以得到 CA 的证书,这个证书被预装在很多操作系统或浏览器中,用户可以用来验证不同网站的证书合法性。

服务器/客户端证书生成 - 向 CA 申请

1. 选择CA机构:首先需要确定一个权威的数字证书颁发机构,如GlobalSign、DigiCert、Let's Encrypt等。

2. 提交申请:访问CA机构的官方网站或使用其提供的服务接口提交数字证书的申请。对于企业用户,可能需要提供企业相关信息;个人用户则可能需要个人身份证明。

3. 填写申请表:按照CA机构的要求填写申请表格,包括但不限于个人信息、组织信息、域名信息等,并可能需要声明证书的用途(如服务器证书、电子邮件证书等)。

4. 身份验证:根据CA的不同要求,可能需要通过不同的方式验证身份。企业可能需要提交营业执照、法人身份证明等;个人用户可能需要通过身份证、手机验证码等方式验证。

5. 生成密钥对:在申请过程中,申请者需要生成一个公钥和私钥对。公钥会提交给CA,私钥则需要妥善保管,它是数字证书安全的关键。

6. 审核与颁发:CA机构会对申请信息进行审核,审核通过后,会将包含申请者公钥、身份信息及CA签名的数字证书颁发给申请者,这个过程可能需要几个小时到几天不等。

服务器/客户端证书生成 - 自签名证书

证书也可以是自己签名的,这就需要自己另外生成一对密钥,用以给自己的服务器密钥签名,同时需要自己管理好签名的密钥,再将证书交给使用者用以验证。可以用 openssl 自签名一个证书:

(1)生成 CA 私钥和证书

# 生成CA私钥,使用ECC prime256v1算法生成
openssl ecparam -out ecc_ca.key -name prime256v1 -genkey
# 根据私钥生成CA证书请求  -subj  "\C=CN\ST=FJ\L=XM\O=YaXon\OU=CA\CN=MyRootCA"
openssl req -config /usr/ssl/openssl.cnf -key ecc_ca.key -new -out ecc_ca.req
# 根据私钥和证书请求,生成CA证书
openssl x509 -req -days 365 -in ecc_ca.req -signkey ecc_ca.key -out ecc_ca.pem
rm ecc_ca.req

(2)生成服务端的私钥和证书

# 生成服务端私钥
openssl ecparam -out ecc_server.key -name prime256v1 -genkey
# 生成服务端证书请求,需要提供国家、省市地区和公司等信息  -subj "/C=CN/ST=FJ/L=XM/O=YaXon/OU=server/CN=server"
openssl req -config /usr/ssl/openssl.cnf -key ecc_server.key -new -out ecc_server.req
# 通过CA私钥签发服务端证书
openssl x509 -req -days 365 -in ecc_server.req -CA ecc_ca.pem -CAkey ecc_ca.key -out ecc_server.pem -CAcreateserial
rm ecc_server.req

(3)生成客户端的私钥和证书

# 生成客户端私钥
openssl ecparam -out ecc_client.key -name prime256v1 -genkey
# 生成客户端证书请求 -subj  "/C=CN/ST=FJ/L=XM/O=YaXon/OU=client/CN=client"
openssl req -config /usr/ssl/openssl.cnf -key ecc_client.key -new -out ecc_client.req
# 通过CA私钥签发客户端证书
openssl x509 -req -days 365 -in ecc_client.req -CA ecc_ca.pem -CAkey ecc_ca.key -out ecc_client.pem -CAcreateserial
rm ecc_client.req

生成证书请求文件时,需要输入国家、省份、公司等信息:

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:FUJIAN
Locality Name (eg, city) []:XIAMEN
Organization Name (eg, company) [Internet Widgits Pty Ltd]:YAXON
Organizational Unit Name (eg, section) []:BLUECAT
Common Name (e.g. server FQDN or YOUR name) []:ROOTCA
Email Address []:.

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Signature ok
subject=C = CN, ST = FUJIAN, L = XIAMEN, O = YAXON, OU = BLUECAT, CN = ROOTCA
Getting Private key
...

最终生成以下文件:

ecc_ca.key        // ca密钥
ecc_ca.pem        // ca证书
ecc_ca.srl        // 序列号列表文件,用于跟踪CA所签发的所有证书的序列号,确保每个证书都有一个唯一的序列号。这样可以防止证书重复签发导致的安全问题
ecc_client.key    // 客户端密钥
ecc_client.pem    // 客户端证书,认证过程中发给服务器,服务器用ca证书验证
ecc_server.key    // 服务端密钥
ecc_server.pem    // 服务端证书,认证过程中发给客户端,客户端用ca证书验证

用 ca 证书验证服务端和客户端的证书:

openssl verify -CAfile ecc_ca.pem ecc_server.pem
ecc_server.pem: OK

openssl verify -CAfile ecc_ca.pem ecc_client.pem
ecc_client.pem: OK

OK 表示验证通过。

3.5 数字证书标准

3.5.1 证书格式标准

一张数字证书的内容,遵循的标准是 X.509 标准,它的实现实际上是 ASN. 1 (Abstract Syntax Notation One 抽象语法标记系统第一版)的应用,ASN. 1 规定了数据结构的形式,X.509 规定了数据结构应该包含哪些信息,数字证书通常包含以下内容:

在这里插入图片描述
在 X.509 的基础上,还有 p7、p10、p12 三种对其补充的标准,它们同样属于 ASN. 1 标记语言的应用,所以数字证书相关的标准可以总结为以下四种:

1. PKI ITU-T X509标准,基本标准(.DER .PEM .CER .CRT)

2. PKCS#7 加密消息语法标准,用于封装加密消息、签名消息、签名及加密消息等,比如在SSL握手过程中,服务器可能会发送其证书链,这些证书信息可以采用PKCS#7格式封装。(.P7B .P7C .SPC .P7R)

3. PKCS#10 证书请求标准,定义了证书签名请求(Certificate Signing Request, CSR)的格式。当一个实体(如用户或设备)想要从证书颁发机构(CA)获取一个X.509证书时,它会创建一个PKCS#10请求,这个请求中包含了主体的识别信息(如公钥、主体名称等),并用请求者的私钥进行签名。CA基于这个请求来验证请求者的身份,并据此签发X.509证书。(.p10)

4. PKCS#12 个人信息交换标准,也被称为PFX(Personal Information Exchange)格式,提供了一种存储和传输用户身份和私钥信息的方式,它通常包含用户的私钥、公钥对应的证书,以及可能的证书链和用于保护私钥的口令。对应的场景比如:将私钥和证书合并成PKCS#12文件,然后发给其他设备,其他设备再解密导入,从而部署自己的环境。(.pfx *.p12)
3.5.2 证书编码

生成证书的编码格式有两种:DER(Distinguished Encoding Rules 唯一编码规则) 和 PEM(Privacy Enhanced Mail 隐私增强邮件),它们最大的区别是是否经过 base 64 编码,DER 格式的证书经过 BASE64 编码后再按 64 字节分配到每一行然在数据头尾添加分割字符,就变成了 BASE64 格式的证书。

3.5.3 常见文件扩展名
1、.pem (Privacy Enhanced Mail) - 用于存储证书、私钥、公钥和证书请求或其它 ASN. 1 结构化的数据,是 PEM 编码的原始文件扩展名。
2、.key - 通常用于存储未加密的私钥或加密的私钥。
3、.pub - 用于存储公钥,通常为文本文件,用于 SSH 认证等场景。
4、.crt/.cert/.cer - 这些扩展名都常用来表示X.509 证书或证书链文件。采用 PEM 或 DER 编码。通常,.cer 更倾向于指代 DER 编码的证书。
5、.csr (Certificate Signing Request) - 证书签名请求文件,用于向证书颁发机构(CA)申请证书,包含公钥和一些身份信息。
6、.der (Distinguished Encoding Rules) - 用于存储证书、私钥、公钥和证书请求或其它 ASN.1 结构化的数据,是 DER 编码的原始文件扩展名。
7、.p7b - 用于存储证书链的文件,不含私钥。
8、.p10 - 用于存储证书申请者的公钥、识别信息、签名等信息,然后通过该文件向证书颁发机构(Certificate Authority, CA)请求数字证书。
9、.p12/.pfx - 用于存储证书、私钥(可选加密)以及可能的证书链,原始文件中证书采用了DER编码,其他信息则采用不同的编码。

4、HTTPS 数据交互流程

根据抓取的 wireshark 数据来介绍流程:
在这里插入图片描述

(1)TCP三次握手(SYN交换)

第一步(Client -> Server):客户端向服务器发送一个TCP SYN(同步序列编号,Synchronize)报文。这个报文包含客户端想要连接的端口号和一个初始序列号(Initial Sequence Number, ISN)。标志位SYN设置为1,表示这是一个连接请求,Seq(Sequence Number)设为一个随机数X。

第二步(Server -> Client):服务器收到客户端的SYN后,回复一个TCP报文给客户端,这个报文包含SYN(标志位同样为1,表示这是服务器同意建立连接的响应)和ACK(确认位,Acknowledgment)。服务器也会选择一个初始序列号Y,并且确认号(Acknowledge Number)设为客户端的ISN加1(即X+1),表示它已经成功接收到了客户端的SYN报文。

第三步(Client -> Server):客户端收到服务器的SYN+ACK报文后,再发送一个ACK报文给服务器,确认号设为服务器的ISN加1(即Y+1),表示客户端已收到服务器的SYN报文。至此,TCP连接建立完成,可以开始进行数据传输。

(2)TLS/SSL握手

Client Hello:
客户端发送一个Client Hello消息给服务器,这个消息中包含客户端支持的SSL/TLS版本、加密套件列表、压缩方法以及一个随机生成的客户端随机数(Client Random)。

Server Hello:
服务器从客户端提供的选项中选择一个最优的协议版本、加密套件和压缩方法,并回送一个Server Hello消息,消息包含服务器选择的这些信息,以及一个服务器随机数(Server Random)。

Certificate:
服务器发送其数字证书给客户端,证书中包含服务器的公钥,并由一个受信任的证书颁发机构(CA)签名,以证明服务器的身份。

Server Key Exchange (可选):
如果使用的密钥交换算法有要求,服务器会发送一个Server Key Exchange消息,里面包含一些用于密钥交换的额外参数。

Server Hello Done:
服务器发送Server Hello Done消息,通知客户端它已经发送完了所有的握手消息。

---
Certificate Request:如果是双向认证,服务端还会向客户端发送该报文请求客户端的证书
Client Key Exchange and Certificate (if required):客户端收到`Certificate Request`后,会发送自己的证书给服务器,同时还会发送一个`Certificate Verify`消息,包含一个签名,该签名是用客户端私钥对之前握手消息的散列值进行加密的结果。这使得服务器能够验证客户端证书的真实性及其持有者的身份,随后再进行`Client Key Exchange`。
---

Client Key Exchange:
客户端利用接收到的服务器公钥,来加密一个预主密钥(Pre-Master Secret),并发送给服务器。这一步是安全的关键,因为只有服务器可以用其私钥解密这个预主密钥,服务器收到预主密钥后再结合之前的随机数等信息,生成会话密钥。

Change Cipher Spec:
服务器会发送Change Cipher Spec消息给客户端,表明随后的消息将使用新协商的密钥和算法进行加密,客户端收到后算出会话密钥,同时也向服务器发送Change Cipher Spec。

Finished(Encrypted Handshake Message中包含Finished消息):
客户端首先发送一个Finished消息,该消息是前面所有握手消息的哈希值,用会话密钥加密,作为握手的完整性校验。
服务器收到并验证客户端的Finished消息后,也会用会话密钥加密并发送自己的Finished消息。

(3)数据传输:握手成功后,客户端和服务器之间开始使用协商好的加密算法和密钥进行安全的数据传输。

(4)连接关闭:数据传输完毕后,双方通过TCP的四次挥手过程来关闭连接。

可以利用 openssl 调试 SSL 过程,数据较长,有兴趣的可以研究

openssl s_client -connect example.com:443 -debug -showcerts

CONNECTED(00000004)
write to 0x8000a50a0 [0x8000b00d0] (313 bytes => 313 (0x139))
0000 - 16 03 01 01 34 01 00 01-30 03 03 d4 9f 8c 29 46   ....4...0.....)F
0010 - 66 d0 de 5b 95 46 70 b6-96 a3 a3 0b e1 13 85 9b   f..[.Fp.........
0020 - a7 e1 c5 f7 d2 64 55 e0-2f 80 e6 20 8c 36 e6 08   .....dU./.. .6..
0030 - fb c3 3f 00 f0 80 1a 57-08 64 80 71 fe 4e 84 fd   ..?....W.d.q.N..
0040 - 3a e9 90 b1 f4 2f 0a 1c-1a 3a 05 64 00 3e 13 02   :..../...:.d.>..
0050 - 13 03 13 01 c0 2c c0 30-00 9f cc a9 cc a8 cc aa   .....,.0........
0060 - c0 2b c0 2f 00 9e c0 24-c0 28 00 6b c0 23 c0 27   .+./...$.(.k.#.'
0070 - 00 67 c0 0a c0 14 00 39-c0 09 c0 13 00 33 00 9d   .g.....9.....3..
0080 - 00 9c 00 3d 00 3c 00 35-00 2f 00 ff 01 00 00 a9   ...=.<.5./......
0090 - 00 00 00 10 00 0e 00 00-0b 65 78 61 6d 70 6c 65   .........example
00a0 - 2e 63 6f 6d 00 0b 00 04-03 00 01 02 00 0a 00 0c   .com............
00b0 - 00 0a 00 1d 00 17 00 1e-00 19 00 18 00 23 00 00   .............#..
00c0 - 00 16 00 00 00 17 00 00-00 0d 00 30 00 2e 04 03   ...........0....
00d0 - 05 03 06 03 08 07 08 08-08 09 08 0a 08 0b 08 04   ................
00e0 - 08 05 08 06 04 01 05 01-06 01 03 03 02 03 03 01   ................
00f0 - 02 01 03 02 02 02 04 02-05 02 06 02 00 2b 00 09   .............+..
0100 - 08 03 04 03 03 03 02 03-01 00 2d 00 02 01 01 00   ..........-.....
0110 - 33 00 26 00 24 00 1d 00-20 ea 6d e8 d8 69 69 17   3.&.$... .m..ii.
0120 - f0 6e 7c f2 fb b5 4b 92-f6 fb e5 75 c7 b4 57 40   .n|...K....u..W@
0130 - a5 2e 7a e4 a8 da 67 8b-62                        ..z...g.b
read from 0x8000a50a0 [0x8000aaca3] (5 bytes => 5 (0x5))
0000 - 16 03 03 00 58                                    ....X
read from 0x8000a50a0 [0x8000aaca8] (88 bytes => 88 (0x58))
0000 - 02 00 00 54 03 03 cf 21-ad 74 e5 9a 61 11 be 1d   ...T...!.t..a...
0010 - 8c 02 1e 65 b8 91 c2 a2-11 16 7a bb 8c 5e 07 9e   ...e......z..^..
0020 - 09 e2 c8 a8 33 9c 20 8c-36 e6 08 fb c3 3f 00 f0   ....3. .6....?..
0030 - 80 1a 57 08 64 80 71 fe-4e 84 fd 3a e9 90 b1 f4   ..W.d.q.N..:....
0040 - 2f 0a 1c 1a 3a 05 64 13-02 00 00 0c 00 2b 00 02   /...:.d......+..
0050 - 03 04 00 33 00 02 00 17-                          ...3....
write to 0x8000a50a0 [0x8000b00d0] (352 bytes => 352 (0x160))
0000 - 14 03 03 00 01 01 16 03-03 01 55 01 00 01 51 03   ..........U...Q.
0010 - 03 d4 9f 8c 29 46 66 d0-de 5b 95 46 70 b6 96 a3   ....)Ff..[.Fp...
0020 - a3 0b e1 13 85 9b a7 e1-c5 f7 d2 64 55 e0 2f 80   ...........dU./.
0030 - e6 20 8c 36 e6 08 fb c3-3f 00 f0 80 1a 57 08 64   . .6....?....W.d
0040 - 80 71 fe 4e 84 fd 3a e9-90 b1 f4 2f 0a 1c 1a 3a   .q.N..:..../...:
0050 - 05 64 00 3e 13 02 13 03-13 01 c0 2c c0 30 00 9f   .d.>.......,.0..
0060 - cc a9 cc a8 cc aa c0 2b-c0 2f 00 9e c0 24 c0 28   .......+./...$.(
0070 - 00 6b c0 23 c0 27 00 67-c0 0a c0 14 00 39 c0 09   .k.#.'.g.....9..
0080 - c0 13 00 33 00 9d 00 9c-00 3d 00 3c 00 35 00 2f   ...3.....=.<.5./
0090 - 00 ff 01 00 00 ca 00 00-00 10 00 0e 00 00 0b 65   ...............e
00a0 - 78 61 6d 70 6c 65 2e 63-6f 6d 00 0b 00 04 03 00   xample.com......
00b0 - 01 02 00 0a 00 0c 00 0a-00 1d 00 17 00 1e 00 19   ................
00c0 - 00 18 00 23 00 00 00 16-00 00 00 17 00 00 00 0d   ...#............
00d0 - 00 30 00 2e 04 03 05 03-06 03 08 07 08 08 08 09   .0..............
00e0 - 08 0a 08 0b 08 04 08 05-08 06 04 01 05 01 06 01   ................
00f0 - 03 03 02 03 03 01 02 01-03 02 02 02 04 02 05 02   ................
0100 - 06 02 00 2b 00 09 08 03-04 03 03 03 02 03 01 00   ...+............
0110 - 2d 00 02 01 01 00 33 00-47 00 45 00 17 00 41 04   -.....3.G.E...A.
0120 - 42 b6 c9 77 d5 23 b0 ef-30 23 db 1e 42 44 6d 4e   B..w.#..0#..BDmN
0130 - 14 11 97 78 2e 04 bd 9a-20 ee 87 0a a8 d8 86 09   ...x.... .......
0140 - ed 65 87 29 f4 f4 c3 ed-de d8 e3 51 3a cc e9 4e   .e.).......Q:..N
0150 - 53 29 48 a5 6b de a5 63-76 6f 52 f9 d4 b9 a4 40   S)H.k..cvoR....@
read from 0x8000a50a0 [0x8000aaca3] (5 bytes => 5 (0x5))
0000 - 14 03 03 00 01                                    .....
read from 0x8000a50a0 [0x8000aaca8] (1 bytes => 1 (0x1))
0000 - 01                                                .
read from 0x8000a50a0 [0x8000aaca3] (5 bytes => 5 (0x5))
0000 - 16 03 03 00 9b                                    .....
read from 0x8000a50a0 [0x8000aaca8] (155 bytes => 155 (0x9B))
0000 - 02 00 00 97 03 03 33 4b-62 41 5b 1b bd 96 18 69   ......3KbA[....i
0010 - 85 c4 8e 0d 28 a3 ed 28-dd ad b8 3c 68 44 ca 29   ....(..(...<hD.)
0020 - f7 87 06 6c 0d c1 20 8c-36 e6 08 fb c3 3f 00 f0   ...l.. .6....?..
0030 - 80 1a 57 08 64 80 71 fe-4e 84 fd 3a e9 90 b1 f4   ..W.d.q.N..:....
0040 - 2f 0a 1c 1a 3a 05 64 13-02 00 00 4f 00 2b 00 02   /...:.d....O.+..
0050 - 03 04 00 33 00 45 00 17-00 41 04 9c cf 19 69 4f   ...3.E...A....iO
0060 - 4c 3d 68 24 42 d2 9a 55-f7 4e 29 31 35 6d 64 e0   L=h$B..U.N)15md.
0070 - 71 be 5a 00 83 1b 9b 5d-9f 31 ae 6f 31 b4 72 0b   q.Z....].1.o1.r.
0080 - c5 83 cf 51 d1 a6 b5 65-30 a1 bb e4 ed 8a c1 ec   ...Q...e0.......
0090 - d3 d8 aa ce 4a 8c af b0-76 14 59                  ....J...v.Y
read from 0x8000a50a0 [0x8000aaca3] (5 bytes => 5 (0x5))
0000 - 17 03 03 00 17                                    .....
read from 0x8000a50a0 [0x8000aaca8] (23 bytes => 23 (0x17))
0000 - 8b c5 6d 1d ca e7 fc 4c-f3 d5 2c ec d3 96 cd 28   ..m....L..,....(
0010 - a0 ad 5a 0e ed b3 ca                              ..Z....
read from 0x8000a50a0 [0x8000aaca3] (5 bytes => 5 (0x5))
0000 - 17 03 03 0c 61                                    ....a
read from 0x8000a50a0 [0x8000aaca8] (3169 bytes => 3169 (0xC61))
0000 - 8d 98 f0 09 29 51 0e dc-55 db 06 c9 51 52 07 cb   ....)Q..U...QR..
0010 - c1 cd 0e b4 7e e0 10 0f-eb 0e 01 01 bb ed d1 16   ....~...........
0020 - e6 f3 ec 45 5c 82 56 3c-ba a8 36 bd 9f d1 87 99   ...E\.V<..6.....
0030 - 47 e4 26 22 f8 80 eb 02-e5 02 f6 bb 9b 8b b4 7c   G.&"...........|
0040 - 4a de 4f 05 75 b1 29 8b-df 47 66 59 8a 6a 17 3c   J.O.u.)..GfY.j.<
0050 - b6 cd 6c 36 dc 1c a7 4d-74 06 8c dc 00 00 0f e6   ..l6...Mt.......
0060 - 30 66 ff 0e 4a 47 b9 88-49 00 53 d0 3c 9b e2 58   0f..JG..I.S.<..X
0070 - 56 80 41 5f 29 af e5 ac-a7 e0 15 48 b5 15 95 8c   V.A_)......H....
0080 - bb bd 7f 1f 8b 00 88 64-05 45 13 5a a6 98 ad a7   .......d.E.Z....
0090 - e6 ab 90 c4 20 2f e8 11-6c 74 e3 26 07 a3 49 44   .... /..lt.&..ID
00a0 - bf cd 75 c2 3e 9b af 32-88 46 01 c9 41 12 f8 71   ..u.>..2.F..A..q
00b0 - 10 8e 26 e6 ea 05 7f 61-d4 9e 9b 51 c6 f8 74 6c   ..&....a...Q..tl
00c0 - c6 0a e4 9a 48 c3 2a e3-d1 82 38 a9 14 c6 41 61   ....H.*...8...Aa
00d0 - b3 4b 55 57 9a 0f 95 35-92 11 fd d2 8c ab d5 76   .KUW...5.......v
00e0 - 87 71 09 9d 36 92 49 bc-f9 fb 9d 29 9b db ce a6   .q..6.I....)....
00f0 - fd a1 48 89 c0 09 eb 9e-6d d3 94 06 90 45 5f e4   ..H.....m....E_.
0100 - 33 67 ba d2 2b 46 17 6c-f0 d0 eb f2 a0 b3 c8 61   3g..+F.l.......a
0110 - 43 67 ca 72 87 a2 54 6e-6b c5 4f 9e a6 cc b7 f8   Cg.r..Tnk.O.....
0120 - 7f a5 52 c0 59 5c 8c cc-1e d9 95 d5 c8 2e ea b7   ..R.Y\..........
0130 - b2 ee 1f f6 6d ac be 08-93 7d e9 9b 8c ff e3 8c   ....m....}......
0140 - 9f 70 3d b4 8e c2 c4 c3-d0 d7 ec 7b 87 73 0a cc   .p=........{.s..
0150 - 33 22 bc 56 87 17 d8 c0-b9 2f 61 96 b0 e8 31 8a   3".V...../a...1.
0160 - 16 f5 06 f2 66 f2 83 51-3c 44 a9 81 33 17 47 90   ....f..Q<D..3.G.
0170 - 90 f4 c0 95 50 4b cc a5-17 77 91 9a 12 49 a9 22   ....PK...w...I."
0180 - a9 dd 93 2f f6 0a ec 7c-26 d3 0c 43 59 ce e7 7a   .../...|&..CY..z
0190 - 86 11 b9 78 f0 4e a3 0c-84 d8 a9 a8 2b 6f 44 57   ...x.N......+oDW
01a0 - 83 f2 2a 3c 19 c2 5d cd-3e 43 7b 4e 9f ac 39 cd   ..*<..].>C{N..9.
01b0 - bc 91 34 2d f7 fc 71 db-c6 3c 2c 85 56 85 9c c4   ..4-..q..<,.V...
01c0 - fb a5 38 6f 62 7f 03 98-26 96 37 06 a9 5b 52 eb   ..8ob...&.7..[R.
01d0 - f8 49 a7 b2 eb 91 fc f8-22 2b f7 12 bb 07 14 dd   .I......"+......
01e0 - 37 0e 4f 06 32 5d ad 20-30 03 71 53 b6 11 1b 24   7.O.2]. 0.qS...$
01f0 - 57 37 d9 83 3f 71 b3 86-26 e5 f5 b6 2f 59 ac a9   W7..?q..&.../Y..
0200 - 9e 1d 71 1f 33 30 7c 5a-a9 34 c2 8a 77 43 94 64   ..q.30|Z.4..wC.d
0210 - 02 40 7d 78 4f d7 16 84-d4 58 5b 08 56 5f 0c 47   .@}xO....X[.V_.G
0220 - 75 1a be 38 4e 08 cc bf-53 56 47 47 5c 5a 60 ae   u..8N...SVGG\Z`.
0230 - a2 84 58 e2 3a ed c0 8e-b9 d0 94 03 d3 d4 aa c4   ..X.:...........
0240 - 1f 38 b0 a3 e0 02 d6 e5-54 6c 25 e2 2e 05 f2 21   .8......Tl%....!
0250 - ef 05 b1 7a 80 e7 95 89-4f b8 03 2d 39 66 4f 29   ...z....O..-9fO)
0260 - fa 9a ab 7e 86 76 e6 57-e0 70 ae ff 19 1c 61 2b   ...~.v.W.p....a+
0270 - 3e e5 46 5d 48 e5 0b 84-35 cf e3 d4 51 89 5c a0   >.F]H...5...Q.\.
0280 - fd 71 aa f7 50 cc d3 b3-55 a8 9c c5 8a c0 80 dd   .q..P...U.......
0290 - 20 2d 5a 83 0f 33 2b b9-2f 71 86 30 0f 61 13 7b    -Z..3+./q.0.a.{
02a0 - 91 e6 d7 c9 8b e0 32 d6-6f 72 7b 5c f4 5d c5 23   ......2.or{\.].#
02b0 - 06 b2 50 1e df 53 1d 7d-f1 74 27 a2 a4 a0 19 fe   ..P..S.}.t'.....
02c0 - 76 47 57 43 59 88 fd 35-2e 1f 5c 29 08 16 d8 bf   vGWCY..5..\)....
02d0 - 63 1a bd 2d 11 16 be 89-54 84 f6 3f 72 a2 0b ad   c..-....T..?r...
02e0 - 87 ae 35 31 b9 b4 af 3f-a2 10 90 87 a6 05 51 4a   ..51...?......QJ
02f0 - 2b 28 81 64 dc b9 e7 4a-fc 44 98 6f 67 78 15 ff   +(.d...J.D.ogx..
0300 - b9 61 f4 f6 01 e4 33 fa-15 02 9e 72 57 a0 97 57   .a....3....rW..W
0310 - 9e 02 0d e5 db 2c 81 a7-57 ed 80 6f 05 55 c8 24   .....,..W..o.U.$
0320 - ee 8d 34 61 6d 82 de 4b-5e 59 01 54 44 25 47 2f   ..4am..K^Y.TD%G/
0330 - e3 aa a8 92 c0 df c1 86-9b ac f2 7c e8 65 73 61   ...........|.esa
0340 - 02 0b 33 a3 dd e5 3e b6-5d cd b4 fb 2c e5 6e 17   ..3...>.]...,.n.
0350 - 9c 7d f8 a3 37 fc 97 78-48 41 20 c9 2a 22 97 04   .}..7..xHA .*"..
0360 - 3e 31 bf e5 9f 38 9b 7e-79 4d 9d fb 2f 2c 21 fa   >1...8.~yM../,!.
0370 - b7 d9 f9 cc 24 d1 ca cd-60 4e 24 83 96 0c 8a 1c   ....$...`N$.....
0380 - 16 11 fe 91 41 9a 00 da-61 02 e6 4a da dc 90 a8   ....A...a..J....
0390 - 24 90 34 78 2a 96 9f c6-ed 80 bc 2e 88 88 4b 5f   $.4x*.........K_
03a0 - ef 8d 2c a4 2a 68 91 b6-30 23 29 63 13 81 8e 9b   ..,.*h..0#)c....
03b0 - 5a 31 12 51 a1 b7 86 3c-d9 f6 7b d6 a7 af 45 13   Z1.Q...<..{...E.
03c0 - 3b 08 13 6b 65 54 b7 95-d1 9d cc 4c ad 99 a2 2f   ;..keT.....L.../
03d0 - f6 1a 30 9c 9e 5c 32 bc-ca dd 3d 3e 09 fe ca 42   ..0..\2...=>...B
03e0 - 5a 4f 9a 2a 44 b5 98 46-a6 62 b0 d4 e0 c4 9c 5f   ZO.*D..F.b....._
03f0 - be 85 af 3d 8c 53 ff b2-ea 0e 50 d3 00 b4 72 46   ...=.S....P...rF
0400 - 25 4e 69 dc 42 5c fc 7f-9c b2 82 67 54 e0 a0 2e   %Ni.B\.....gT...
0410 - f9 ba 55 4b 23 fa c1 56-3e 0c db 4b 05 e3 93 9d   ..UK#..V>..K....
0420 - f8 c4 81 da 3b 6a cd 62-d0 13 b7 3b c3 40 f4 c3   ....;j.b...;.@..
0430 - 63 eb c3 12 fd 58 23 1f-31 b9 a9 7a 1a c7 13 fb   c....X#.1..z....
0440 - 5d 07 cc 97 36 d9 5f 93-84 df 37 95 16 ce ef 06   ]...6._...7.....
0450 - 04 b7 9d a4 46 dc e6 84-42 8b 5f 28 71 df 4b b8   ....F...B._(q.K.
0460 - b1 38 eb 1d 83 5f 6d 03-b9 2c b9 62 6a 34 84 78   .8..._m..,.bj4.x
0470 - 41 97 59 39 44 0f 3a 27-65 e2 b5 e7 aa 19 e1 40   A.Y9D.:'e......@
0480 - db 52 62 89 a1 5b a6 7a-90 3a 62 04 fd fd de b1   .Rb..[.z.:b.....
0490 - b4 42 09 b9 15 de d0 0f-87 b2 90 38 51 a3 09 ec   .B.........8Q...
04a0 - 7c 2b 5d 7d dc 8a c0 c2-7d 21 a5 72 cb 62 99 78   |+]}....}!.r.b.x
04b0 - 36 7c b9 37 73 70 f3 02-fb 1e 5d 29 24 76 cc 12   6|.7sp....])$v..
04c0 - f1 b9 75 3c ea 96 cd f1-e1 2e 73 ea 0b 9f de 44   ..u<......s....D
04d0 - 16 0c db b9 13 ab 23 29-2e 18 46 3a 95 61 4a 38   ......#)..F:.aJ8
04e0 - 89 12 49 69 9d 96 f5 ca-5b 06 6e 2f 90 db 8e 9c   ..Ii....[.n/....
04f0 - 24 3b d2 42 99 b7 4d a0-9f 0a b6 e5 6f 89 a2 7b   $;.B..M.....o..{
0500 - 43 1f a2 b5 1b 96 fb 69-d2 bb 7f 80 f3 8a f9 9c   C......i........
0510 - d4 0b 40 d4 0e 9a 48 d3-83 f4 d6 fc a1 4c 85 f3   ..@...H......L..
0520 - 27 98 31 6a fd 12 1b e4-e1 4e 74 14 19 5f 15 c8   '.1j.....Nt.._..
0530 - ff 71 11 dd 76 f0 dd 59-ae f6 00 5e 0b 46 75 77   .q..v..Y...^.Fuw
0540 - 10 25 69 47 89 f4 26 1b-1f ea 66 5b 96 f5 54 ec   .%iG..&...f[..T.
0550 - cc 9f cc aa b4 8a 40 ef-d7 1b 38 f0 5c e2 30 e8   ......@...8.\.0.
0560 - d6 86 9c 9a c7 63 79 c5-3e f8 3c 80 ce 8a 5a ef   .....cy.>.<...Z.
0570 - 78 7e 64 53 4f 76 03 d8-52 33 67 be 0e e1 1b f7   x~dSOv..R3g.....
0580 - 53 56 26 71 35 8c b4 59-34 9e d9 84 bf fc ea 07   SV&q5..Y4.......
0590 - b2 d2 2b 8b 76 37 5a 27-b2 b8 12 42 58 7b 36 92   ..+.v7Z'...BX{6.
05a0 - f9 d9 e7 1b c4 9c 9a f1-b4 f8 73 64 60 36 4a fa   ..........sd`6J.
05b0 - c0 5e f6 f6 e3 f0 9b 1c-fa 1e ff df 74 23 44 12   .^..........t#D.
05c0 - 99 8f 9f d8 be 18 f2 31-fe 7a 3e e6 19 9a 41 b2   .......1.z>...A.
05d0 - 06 de d4 3d a1 94 38 3f-71 fd ee 59 e9 30 e1 5f   ...=..8?q..Y.0._
05e0 - 14 bc 60 7a 1a f4 be 80-0f 1f b5 35 19 93 eb 55   ..`z.......5...U
05f0 - 14 67 11 9c 1f 34 b2 01-dd 76 8b a2 29 e0 11 02   .g...4...v..)...
0600 - 6e 16 71 7b 5a 42 a6 27-c4 45 7a 63 db 10 d1 9c   n.q{ZB.'.Ezc....
0610 - cd 68 11 d9 f4 31 2c bc-b1 64 bd 25 75 d8 a6 9f   .h...1,..d.%u...
0620 - f8 fe 33 6a 37 4d b1 2f-b2 67 0e 9c 58 80 56 b4   ..3j7M./.g..X.V.
0630 - 44 c2 fa 1d 07 f9 75 31-ee 7a 1c 5f 8d 05 68 15   D.....u1.z._..h.
0640 - cc eb e1 ba 8c 3c 75 63-54 de 91 e0 2a 06 1a 02   .....<ucT...*...
0650 - d0 e2 cc 88 76 db 83 c9-fa 0b bb 91 41 87 ac cc   ....v.......A...
0660 - 74 73 b9 21 c7 14 08 62-6c e4 5b fc 7c de 3f 4a   ts.!...bl.[.|.?J
0670 - c1 aa ac c1 d0 b7 45 c1-50 a2 3d d1 07 3e b9 2f   ......E.P.=..>./
0680 - 53 76 4c ef 8a 34 0b 66-2a 52 bc 56 ab ce ee 1b   SvL..4.f*R.V....
0690 - 96 e0 75 d7 3d c3 a9 ea-ee 9b 26 67 8c ff 6c 82   ..u.=.....&g..l.
06a0 - 07 cd 0f e1 94 f0 b4 9b-d5 fb 93 a9 09 d0 33 9b   ..............3.
06b0 - 11 90 2a 53 83 a6 53 f3-a0 06 b6 2d 7d f5 4b 36   ..*S..S....-}.K6
06c0 - 5a 61 56 5b 78 ff c3 ee-ce df ec 36 e9 80 da 21   ZaV[x......6...!
06d0 - 29 e2 39 85 83 23 42 43-d0 21 82 7f 63 74 60 57   ).9..#BC.!..ct`W
06e0 - ff f0 fc 3c dc 2f b6 ed-d2 9c 2e 25 7c 96 84 12   ...<./.....%|...
06f0 - cd 65 17 71 45 38 1a 03-1c f0 68 86 3f 6d 0f 93   .e.qE8....h.?m..
0700 - 15 82 19 c8 fe e6 54 eb-c2 00 ce bc 0e 8a cf 1f   ......T.........
0710 - 6c 7d 20 b9 2f 24 de c5-a7 f8 5d b0 c8 3b f7 e0   l} ./$....]..;..
0720 - 8b fe 14 7a c7 72 bd 8a-09 c4 c9 75 be 1e 9a d3   ...z.r.....u....
0730 - 0f e0 2d 9e eb 9b 6a 6f-f5 a1 16 de fc 20 cb 08   ..-...jo..... ..
0740 - 1b 0c f2 22 1d ce 21 16-e8 65 a4 28 59 f8 6f 14   ..."..!..e.(Y.o.
0750 - a0 7f 6f 87 e9 d3 ab 50-cf 80 7b 60 9d 4e 1b 12   ..o....P..{`.N..
0760 - e8 b7 6c 4d a5 0f 43 e2-6d 69 5e 8a ec df 8e 04   ..lM..C.mi^.....
0770 - 38 71 34 85 19 1b 40 37-40 2e 15 21 26 aa db 02   8q4...@7@..!&...
0780 - 43 5e e7 b6 d2 9f 1b b6-f3 2f b0 a3 67 41 e3 07   C^......./..gA..
0790 - a4 5b 1f 14 62 74 e5 72-33 94 d4 a7 93 67 3d 41   .[..bt.r3....g=A
07a0 - 5b ac ad 1a 5e 6b 5c dd-c0 0a 2a 6f 72 f8 c1 65   [...^k\...*or..e
07b0 - 45 81 45 10 4a b9 23 d2-3f 3f e1 aa f2 47 2f 6b   E.E.J.#.??...G/k
07c0 - 6e 20 3d fb fa eb b3 5e-64 6e 38 18 27 d8 b2 04   n =....^dn8.'...
07d0 - 33 f9 62 06 92 50 3a 6d-45 02 5c 1b 44 64 6e d0   3.b..P:mE.\.Ddn.
07e0 - 60 ec b8 e3 e1 c4 7f 3a-90 26 61 21 74 c6 4c ad   `......:.&a!t.L.
07f0 - ec 25 6c a7 9d 7c 87 45-78 db 02 e5 f8 8f 1c 2f   .%l..|.Ex....../
0800 - e6 5d 70 b0 b9 ef a9 a0-20 0c bd 59 ae 1b ee ae   .]p..... ..Y....
0810 - cf 3a 58 fa 0e 54 1c 4d-c5 07 7c 24 5c b5 c9 50   .:X..T.M..|$\..P
0820 - 6d b7 e3 b6 d8 5a 5c 53-7f 36 97 7c 4c f0 40 24   m....Z\S.6.|L.@$
0830 - c2 64 1c 75 06 85 8f fb-3a 74 ff 7b 46 ee 67 75   .d.u....:t.{F.gu
0840 - eb 3e ca 2d 41 80 aa 02-44 32 40 bd 7a e9 a6 bd   .>.-A...D2@.z...
0850 - 7c f0 1f 9d 2e cd ef a6-62 57 fe 5b 47 ee ad 4a   |.......bW.[G..J
0860 - 70 77 2f d2 ce b2 fe 67-50 f1 c7 e1 a5 4a bc 98   pw/....gP....J..
0870 - 69 e2 c3 55 52 fb a5 0e-fb d7 6a ae 80 4f c6 b0   i..UR.....j..O..
0880 - 77 fb cc 29 fa cf 73 a9-c5 f3 b9 c3 e4 eb b0 18   w..)..s.........
0890 - ab 81 cf a8 2c a8 19 32-5b eb 2c f6 8b fb 73 de   ....,..2[.,...s.
08a0 - 35 06 31 74 3a f4 e8 32-04 52 79 6e 8d a2 02 a6   5.1t:..2.Ryn....
08b0 - 5e c3 5a 04 df d3 af 6b-20 03 84 0c 67 a2 20 b8   ^.Z....k ...g. .
08c0 - af 2d 6e 3f c4 19 db 30-67 29 18 fe d4 5b 30 86   .-n?...0g)...[0.
08d0 - 7e 6f f3 17 dc 31 8f 2c-c4 db eb ec 51 9d 8b fb   ~o...1.,....Q...
08e0 - e1 d8 26 d5 d9 fb 92 7b-4b 9b 39 5d d7 17 86 d0   ..&....{K.9]....
08f0 - 86 55 eb ba 1e 94 7a 94-99 66 79 57 a4 93 32 67   .U....z..fyW..2g
0900 - bd fc 4b ad 0d 98 7a ca-0c 82 97 40 f3 15 f6 6b   ..K...z....@...k
0910 - 9a 8c 6d 78 06 32 98 17-62 bf a4 1d 3d 0a 06 68   ..mx.2..b...=..h
0920 - ef 65 ac 54 60 46 23 9e-9a 3b 76 98 19 5d c5 80   .e.T`F#..;v..]..
0930 - f8 07 87 32 39 3c 54 86-b4 05 15 c2 4f df 58 28   ...29<T.....O.X(
0940 - f3 99 70 53 a9 97 39 cd-30 86 08 3d b9 9b de 52   ..pS..9.0..=...R
0950 - 86 61 3d a3 6d 92 76 f1-c2 3b 4f 3b 73 d4 a0 f2   .a=.m.v..;O;s...
0960 - 81 94 bd da 32 fc 5f ad-ee de f9 2c 66 25 9f f3   ....2._....,f%..
0970 - 8e 20 1e e0 03 3b 25 04-5e 49 37 a7 f0 72 23 e9   . ...;%.^I7..r#.
0980 - 47 13 4a 49 22 88 e3 30-a8 13 8f db 3f 20 88 37   G.JI"..0....? .7
0990 - 72 0d f3 2d 8d 9c 61 1a-52 7f eb d3 5b 20 73 86   r..-..a.R...[ s.
09a0 - 8e dc a1 11 f7 eb 38 87-4b fa a2 70 89 38 9d d1   ......8.K..p.8..
09b0 - ff 2a d2 14 12 8c 66 68-60 d7 31 3f 5f 69 12 d5   .*....fh`.1?_i..
09c0 - 8d ec 9d 1f 93 9e 99 1d-d0 40 6b ca f1 8a ff a2   .........@k.....
09d0 - f3 3f aa 35 f0 91 a5 d7-8c 36 48 5a 9e 74 e6 9e   .?.5.....6HZ.t..
09e0 - a8 bf 07 a3 95 5b e5 dc-76 f7 ee 24 0f 7d ce e7   .....[..v..$.}..
09f0 - 49 c7 94 4a ab 70 0e d7-9f eb 22 14 e7 a6 6b 7e   I..J.p...."...k~
0a00 - ca c9 44 dc 66 a7 18 35-e0 c5 fb fb 26 33 e9 59   ..D.f..5....&3.Y
0a10 - a9 72 4e 21 5e 9e ae ab-ab d3 af 49 83 86 59 fe   .rN!^......I..Y.
0a20 - a9 2d 93 03 59 c0 2f f9-24 3b b2 e2 e8 0d d6 0d   .-..Y./.$;......
0a30 - 2d bd 4d 66 92 04 84 ae-54 5a 87 34 cc 6a 63 33   -.Mf....TZ.4.jc3
0a40 - a4 0f 55 80 e8 1f fb 70-b1 81 4b 9d e3 8d d0 2b   ..U....p..K....+
0a50 - 3e bf ac 0a ea f4 22 ee-63 82 4c cf 8e 41 30 f8   >.....".c.L..A0.
0a60 - 55 16 94 72 bc a5 5d 0c-a1 b3 a4 24 50 00 b4 bd   U..r..]....$P...
0a70 - 66 a5 23 5f 00 9b b4 b1-11 3f d4 39 0a db 7a 8c   f.#_.....?.9..z.
0a80 - c3 0c e2 c4 4e 05 f1 c3-c9 ce c3 2e 25 dd b4 33   ....N.......%..3
0a90 - ec 52 40 b6 6f eb 75 e1-5d 6c 16 b6 c8 32 62 25   .R@.o.u.]l...2b%
0aa0 - b7 c5 f2 ca 29 ba 09 c9-c5 0e 81 de a4 93 58 93   ....).........X.
0ab0 - e6 44 28 27 7c d7 1f d7-02 23 88 03 68 05 19 69   .D('|....#..h..i
0ac0 - d6 47 8c 9a 39 a3 1b 71-c1 55 1c 15 27 33 bb 42   .G..9..q.U..'3.B
0ad0 - 8f e2 d1 62 3f 1f 9e c0-cc 9f d6 3b b7 34 2d 9c   ...b?......;.4-.
0ae0 - 0d 8b 8d 8c 2c ee 39 4c-d7 39 71 34 20 ff ee 62   ....,.9L.9q4 ..b
0af0 - fa f6 6c 2c 39 ec 1a 06-95 1a 33 0b 5e c1 55 30   ..l,9.....3.^.U0
0b00 - ef c1 7d 1c 58 ba 4e 4c-6f dd 9d 4a 4e 8a 8c 11   ..}.X.NLo..JN...
0b10 - ab c4 40 09 51 b3 3b e1-a1 11 60 c2 61 a9 86 b3   ..@.Q.;...`.a...
0b20 - 37 02 ce 19 4c 67 a3 08-7d 24 0b d8 9e 20 80 0d   7...Lg..}$... ..
0b30 - ce 2f 83 0c ae 9d ef 0c-43 56 26 85 cf 86 ba 2b   ./......CV&....+
0b40 - c7 57 4c 4f 9a 27 60 db-71 b1 f4 7c de 8a 5b ab   .WLO.'`.q..|..[.
0b50 - 39 e5 3b e6 7d 23 39 f7-8a 1b f8 87 7e aa 14 9e   9.;.}#9.....~...
0b60 - 37 65 5a 1a 11 d4 4c 9a-d7 1e 39 12 ef 59 52 73   7eZ...L...9..YRs
0b70 - 07 5b d1 9a 82 cf 7d 1e-8a a4 26 f4 89 25 c8 38   .[....}...&..%.8
0b80 - 4a 14 e4 38 ea f8 1d 1d-47 7d 20 76 ee 8a d4 e5   J..8....G} v....
0b90 - d7 4b ec 42 80 3b 79 85-b4 87 5f f5 33 58 b2 b3   .K.B.;y..._.3X..
0ba0 - 91 ab 1b 35 17 8f ec 19-0d 5b 63 a9 d1 ec f0 b0   ...5.....[c.....
0bb0 - bc e6 0e e4 01 f2 85 ec-9f d4 cc 6a cd 88 5b 47   ...........j..[G
0bc0 - e6 0e 91 5c 54 43 27 fa-04 88 17 10 19 c4 a4 56   ...\TC'........V
0bd0 - c1 c5 17 dc b4 b2 dd c4-db 22 20 9b fe d0 ff f3   ........." .....
0be0 - 8b 64 4a 38 69 08 a3 c7-57 e9 3e 40 4e 52 57 4d   .dJ8i...W.>@NRWM
0bf0 - 4b 49 d3 b0 3e 5e 11 bf-58 ba 2f b7 01 4b 1a 16   KI..>^..X./..K..
0c00 - 4d 9c cb 8b 1e 59 95 14-7e f0 71 b9 89 c0 44 78   M....Y..~.q...Dx
0c10 - a1 c1 2a 03 d8 4b 91 74-27 80 de 79 8a 52 af 64   ..*..K.t'..y.R.d
0c20 - 76 4c c4 2b a4 f3 3b 54-61 74 61 ab d7 a3 18 f1   vL.+..;Tata.....
0c30 - 2b 94 4a 68 03 c9 a9 05-c0 3e 52 96 14 70 3b f7   +.Jh.....>R..p;.
0c40 - c2 61 f7 ef cb 2f 00 c5-f9 ca 83 1c 3b 8f dc a6   .a.../......;...
0c50 - 19 cf b3 43 f9 0b 59 17-c6 7c 86 b8 6e cf b1 16   ...C..Y..|..n...
0c60 - 2c                                                ,
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root G2
verify return:1
depth=1 C = US, O = DigiCert Inc, CN = DigiCert Global G2 TLS RSA SHA256 2020 CA1
verify return:1
depth=0 C = US, ST = California, L = Los Angeles, O = Internet\C2\A0Corporation\C2\A0for\C2\A0Assigned\C2\A0Names\C2\A0and\C2\A0Numbers, CN = www.example.org
verify return:1
read from 0x8000a50a0 [0x8000aaca3] (5 bytes => 5 (0x5))
0000 - 17 03 03 01 19                                    .....
read from 0x8000a50a0 [0x8000aaca8] (281 bytes => 281 (0x119))
0000 - 9f 79 4f d4 ea df 9e 56-06 25 cf 99 bd ba a1 30   .yO....V.%.....0
0010 - 2c 47 20 34 74 11 de b7-f6 6a a0 54 c8 7e 37 c8   ,G 4t....j.T.~7.
0020 - 99 b8 c8 79 fb 48 a4 d5-a4 eb 08 06 73 b0 12 9e   ...y.H......s...
0030 - be d7 43 0c 83 15 8f ea-19 97 fa 43 93 31 84 a8   ..C........C.1..
0040 - ab d0 25 55 19 1a 39 d3-6c f8 6b 29 c4 14 12 93   ..%U..9.l.k)....
0050 - ba ed 36 6e 0b 74 c2 5f-e2 92 b3 34 6c 00 2e b8   ..6n.t._...4l...
0060 - dc fe 7f b9 1e d6 4c 4b-70 10 65 dd 52 2b 91 f0   ......LKp.e.R+..
0070 - 26 7d 4a 67 40 30 4b ed-f0 19 d2 12 f7 1d a4 cc   &}Jg@0K.........
0080 - 32 bc ef 0f 0b d4 b5 62-3c 25 81 4a 6a 6a d4 6c   2......b<%.Jjj.l
0090 - 56 bc 97 23 9e f9 25 30-cd 1d 58 09 73 b5 56 f2   V..#..%0..X.s.V.
00a0 - 05 29 35 1a e9 d6 b3 d5-63 f7 ee 6d 8f 68 1b dc   .)5.....c..m.h..
00b0 - 1f 93 fa 38 ee e4 f0 f8-1e 11 e4 a5 0d 80 9d e5   ...8............
00c0 - 9b 01 32 d5 58 9d 00 58-49 d8 eb f6 17 fa 40 91   ..2.X..XI.....@.
00d0 - 35 dd 56 bc 73 fb e5 12-2e 12 11 aa c2 26 06 09   5.V.s........&..
00e0 - cb 4a 37 53 0f 95 ae 8e-c2 82 39 75 47 aa fd 8f   .J7S......9uG...
00f0 - f3 95 35 e2 03 fb 29 e0-25 b0 b0 fc 12 44 44 60   ..5...).%....DD`
0100 - 22 ba bd e6 03 c8 d8 af-84 6d 95 ff 78 18 df ba   "........m..x...
0110 - e1 1f e3 43 b3 71 fb 89-1b                        ...C.q...
read from 0x8000a50a0 [0x8000aaca3] (5 bytes => 5 (0x5))
0000 - 17 03 03 00 45                                    ....E
read from 0x8000a50a0 [0x8000aaca8] (69 bytes => 69 (0x45))
0000 - 18 d0 03 10 75 01 18 9d-21 df d4 6c 12 9f c9 89   ....u...!..l....
0010 - 38 da cc 3f 24 e3 23 53-4f 7b 54 b3 1d ec 7f fc   8..?$.#SO{T.....
0020 - 73 ba c7 a8 04 b3 65 22-55 b6 87 46 57 a8 fa 27   s.....e"U..FW..'
0030 - d1 e0 48 a3 4e 41 2e 2b-09 df a7 52 72 0e e6 e5   ..H.NA.+...Rr...
0040 - 16 67 6e dc 88                                    .gn..
write to 0x8000a50a0 [0x8000b00d0] (74 bytes => 74 (0x4A))
0000 - 17 03 03 00 45 45 b0 18-52 2d ef 07 f7 40 0a 5e   ....EE..R-...@.^
0010 - 76 56 77 c1 03 37 b2 f0-27 1c 08 ac e6 20 55 00   vVw..7..'.... U.
0020 - 06 c7 cd 4b 1a 51 4f 48-2b 78 1c 20 6f 2a c0 b1   ...K.QOH+x. o*..
0030 - 81 61 e9 6f f7 2a ee ee-91 8f 2c 4b 0c f2 af 47   .a.o.*....,K...G
0040 - 92 00 2f 51 84 05 74 c6-60 61                     ../Q..t.`a
---
Certificate chain
 0 s:C = US, ST = California, L = Los Angeles, O = Internet\C2\A0Corporation\C2\A0for\C2\A0Assigned\C2\A0Names\C2\A0and\C2\A0Numbers, CN = www.example.org
   i:C = US, O = DigiCert Inc, CN = DigiCert Global G2 TLS RSA SHA256 2020 CA1
-----BEGIN CERTIFICATE-----
MIIHbjCCBlagAwIBAgIQB1vO8waJyK3fE+Ua9K/hhzANBgkqhkiG9w0BAQsFADBZ
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMTMwMQYDVQQDEypE
aWdpQ2VydCBHbG9iYWwgRzIgVExTIFJTQSBTSEEyNTYgMjAyMCBDQTEwHhcNMjQw
MTMwMDAwMDAwWhcNMjUwMzAxMjM1OTU5WjCBljELMAkGA1UEBhMCVVMxEzARBgNV
BAgTCkNhbGlmb3JuaWExFDASBgNVBAcTC0xvcyBBbmdlbGVzMUIwQAYDVQQKDDlJ
bnRlcm5ldMKgQ29ycG9yYXRpb27CoGZvcsKgQXNzaWduZWTCoE5hbWVzwqBhbmTC
oE51bWJlcnMxGDAWBgNVBAMTD3d3dy5leGFtcGxlLm9yZzCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAIaFD7sO+cpf2fXgCjIsM9mqDgcpqC8IrXi9wga/
9y0rpqcnPVOmTMNLsid3INbBVEm4CNr5cKlh9rJJnWlX2vttJDRyLkfwBD+dsVvi
vGYxWTLmqX6/1LDUZPVrynv/cltemtg/1Aay88jcj2ZaRoRmqBgVeacIzgU8+zmJ
7236TnFSe7fkoKSclsBhPaQKcE3Djs1uszJs8sdECQTdoFX9I6UgeLKFXtg7rRf/
hcW5dI0zubhXbrW8aWXbCzySVZn0c7RkJMpnTCiZzNxnPXnHFpwr5quqqjVyN/aB
KkjoP04Zmr+eRqoyk/+lslq0sS8eaYSSHbC5ja/yMWyVhvMCAwEAAaOCA/IwggPu
MB8GA1UdIwQYMBaAFHSFgMBmx9833s+9KTeqAx2+7c0XMB0GA1UdDgQWBBRM/tAS
TS4hz2v68vK4TEkCHTGRijCBgQYDVR0RBHoweIIPd3d3LmV4YW1wbGUub3Jnggtl
eGFtcGxlLm5ldIILZXhhbXBsZS5lZHWCC2V4YW1wbGUuY29tggtleGFtcGxlLm9y
Z4IPd3d3LmV4YW1wbGUuY29tgg93d3cuZXhhbXBsZS5lZHWCD3d3dy5leGFtcGxl
Lm5ldDA+BgNVHSAENzA1MDMGBmeBDAECAjApMCcGCCsGAQUFBwIBFhtodHRwOi8v
d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQG
CCsGAQUFBwMBBggrBgEFBQcDAjCBnwYDVR0fBIGXMIGUMEigRqBEhkJodHRwOi8v
Y3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRHbG9iYWxHMlRMU1JTQVNIQTI1NjIw
MjBDQTEtMS5jcmwwSKBGoESGQmh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
Q2VydEdsb2JhbEcyVExTUlNBU0hBMjU2MjAyMENBMS0xLmNybDCBhwYIKwYBBQUH
AQEEezB5MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wUQYI
KwYBBQUHMAKGRWh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEds
b2JhbEcyVExTUlNBU0hBMjU2MjAyMENBMS0xLmNydDAMBgNVHRMBAf8EAjAAMIIB
fQYKKwYBBAHWeQIEAgSCAW0EggFpAWcAdABOdaMnXJoQwzhbbNTfP1LrHfDgjhuN
acCx+mSxYpo53wAAAY1b0vxkAAAEAwBFMEMCH0BRCgxPbBBVxhcWZ26a8JCe83P1
JZ6wmv56GsVcyMACIDgpMbEo5HJITTRPnoyT4mG8cLrWjEvhchUdEcWUuk1TAHYA
fVkeEuF4KnscYWd8Xv340IdcFKBOlZ65Ay/ZDowuebgAAAGNW9L8MAAABAMARzBF
AiBdv5Z3pZFbfgoM3tGpCTM3ZxBMQsxBRSdTS6d8d2NAcwIhALLoCT9mTMN9OyFz
IBV5MkXVLyuTf2OAzAOa7d8x2H6XAHcA5tIxY0B3jMEQQQbXcbnOwdJA9paEhvu6
hzId/R43jlAAAAGNW9L8XwAABAMASDBGAiEA4Koh/VizdQU1tjZ2E2VGgWSXXkwn
QmiYhmAeKcVLHeACIQD7JIGFsdGol7kss2pe4lYrCgPVc+iGZkuqnj26hqhr0TAN
BgkqhkiG9w0BAQsFAAOCAQEABOFuAj4N4yNG9OOWNQWTNSICC4Rd4nOG1HRP/Bsn
rz7KrcPORtb6D+Jx+Q0amhO31QhIvVBYs14gY4Ypyj7MzHgm4VmPXcqLvEkxb2G9
Qv9hYuEiNSQmm1fr5QAN/0AzbEbCM3cImLJ69kP5bUjfv/76KB57is8tYf9sh5ik
LGKauxCM/zRIcGa3bXLDafk5S2g5Vr2hs230d/NGW1wZrE+zdGuMxfGJzJP+DAFv
iBfcQnFg4+1zMEKcqS87oniOyG+60RMM0MdejBD7AS43m9us96Gsun/4kufLQUTI
FfnzxLutUV++3seshgefQOy5C/ayi8y1VTNmujPCxPCi6Q==
-----END CERTIFICATE-----
 1 s:C = US, O = DigiCert Inc, CN = DigiCert Global G2 TLS RSA SHA256 2020 CA1
   i:C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root G2
-----BEGIN CERTIFICATE-----
MIIEyDCCA7CgAwIBAgIQDPW9BitWAvR6uFAsI8zwZjANBgkqhkiG9w0BAQsFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
MjAeFw0yMTAzMzAwMDAwMDBaFw0zMTAzMjkyMzU5NTlaMFkxCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxMzAxBgNVBAMTKkRpZ2lDZXJ0IEdsb2Jh
bCBHMiBUTFMgUlNBIFNIQTI1NiAyMDIwIENBMTCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBAMz3EGJPprtjb+2QUlbFbSd7ehJWivH0+dbn4Y+9lavyYEEV
cNsSAPonCrVXOFt9slGTcZUOakGUWzUb+nv6u8W+JDD+Vu/E832X4xT1FE3LpxDy
FuqrIvAxIhFhaZAmunjZlx/jfWardUSVc8is/+9dCopZQ+GssjoP80j812s3wWPc
3kbW20X+fSP9kOhRBx5Ro1/tSUZUfyyIxfQTnJcVPAPooTncaQwywa8WV0yUR0J8
osicfebUTVSvQpmowQTCd5zWSOTOEeAqgJnwQ3DPP3Zr0UxJqyRewg2C/Uaoq2yT
zGJSQnWS+Jr6Xl6ysGHlHx+5fwmY6D36g39HaaECAwEAAaOCAYIwggF+MBIGA1Ud
EwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFHSFgMBmx9833s+9KTeqAx2+7c0XMB8G
A1UdIwQYMBaAFE4iVCAYlebjbuYP+vq5Eu0GF485MA4GA1UdDwEB/wQEAwIBhjAd
BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdgYIKwYBBQUHAQEEajBoMCQG
CCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQAYIKwYBBQUHMAKG
NGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RH
Mi5jcnQwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybDMuZGlnaWNlcnQuY29t
L0RpZ2lDZXJ0R2xvYmFsUm9vdEcyLmNybDA9BgNVHSAENjA0MAsGCWCGSAGG/WwC
ATAHBgVngQwBATAIBgZngQwBAgEwCAYGZ4EMAQICMAgGBmeBDAECAzANBgkqhkiG
9w0BAQsFAAOCAQEAkPFwyyiXaZd8dP3A+iZ7U6utzWX9upwGnIrXWkOH7U1MVl+t
wcW1BSAuWdH/SvWgKtiwla3JLko716f2b4gp/DA/JIS7w7d7kwcsr4drdjPtAFVS
slme5LnQ89/nD/7d+MS5EHKBCQRfz5eeLjJ1js+aWNJXMX43AYGyZm0pGrFmCW3R
bpD0ufovARTFXFZkAdl9h6g4U5+LXUZtXMYnhIHUfoyMo5tS58aI7Dd8KvvwVVo4
chDYABPPTHPbqjc1qCmBaZx2vN4Ye5DUys/vZwP9BFohFrH/6j/f3IL16/RZkiMN
JCqVJUzKoZHm1Lesh3Sz8W2jmdv51b2EQJ8HmA==
-----END CERTIFICATE-----
---
Server certificate
subject=C = US, ST = California, L = Los Angeles, O = Internet\C2\A0Corporation\C2\A0for\C2\A0Assigned\C2\A0Names\C2\A0and\C2\A0Numbers, CN = www.example.org

issuer=C = US, O = DigiCert Inc, CN = DigiCert Global G2 TLS RSA SHA256 2020 CA1

---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 3821 bytes and written 739 bytes
Verification: OK
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
read from 0x8000a50a0 [0x8000aaca3] (5 bytes => 5 (0x5))
0000 - 17 03 03 00 ea                                    .....
read from 0x8000a50a0 [0x8000aaca8] (234 bytes => 234 (0xEA))
0000 - 1d 56 10 d9 db 7c 81 9e-fb 7e 1a 2a 46 23 e8 76   .V...|...~.*F#.v
0010 - e7 83 8f 94 a2 58 f7 40-08 78 3d 44 75 5d 9e a6   .....X.@.x=Du]..
0020 - eb d9 83 87 86 57 64 1f-a8 67 9d f5 76 83 6f c3   .....Wd..g..v.o.
0030 - 18 78 41 12 24 12 ff 6e-d5 44 14 89 5b 12 06 30   .xA.$..n.D..[..0
0040 - 4f c4 59 a5 00 e1 2f 85-12 41 e0 9d 56 29 42 62   O.Y.../..A..V)Bb
0050 - 13 fa 34 5f 1e 73 ee b6-56 10 8e d3 72 b8 71 ee   ..4_.s..V...r.q.
0060 - 32 83 59 52 f5 7e d1 6d-37 47 a3 65 97 ca 92 38   2.YR.~.m7G.e...8
0070 - ae 76 8f f0 cc ff 7f 7c-09 2b 02 18 8c d2 de 98   .v.....|.+......
0080 - 40 66 b1 eb 71 22 63 ed-05 2f 6c c9 32 e9 7e 4d   @f..q"c../l.2.~M
0090 - 94 72 33 d6 90 75 d8 d9-e3 8f c4 11 be 9a b6 bd   .r3..u..........
00a0 - e1 8f b5 a5 6a 2d 75 99-a4 6a 94 35 34 4d ce ca   ....j-u..j.54M..
00b0 - 6e 91 ee 4c 34 e3 15 e7-4e 63 a4 40 cd 3f 7d d9   n..L4...Nc.@.?}.
00c0 - 36 a9 45 22 47 38 0e c2-af e3 b3 9a 62 51 35 c0   6.E"G8......bQ5.
00d0 - 64 57 f2 0b d0 6f 8f 0b-95 b7 98 1d 45 bc 25 cf   dW...o......E.%.
00e0 - 2c 7f fc 03 1d 6e f5 14-fa b6                     ,....n....
---
Post-Handshake New Session Ticket arrived:
SSL-Session:
    Protocol  : TLSv1.3
    Cipher    : TLS_AES_256_GCM_SHA384
    Session-ID: 8B9A7145CEB98402D92565654A334A8FFE1CC4B992BB71E63BCB8205CECF9F56
    Session-ID-ctx:
    Resumption PSK: AAB76E864B4517D3673823E2A5E8BBFB951914E925C7687DEBE581493C4FD91AFA7EA5F02A2B9CC256B8915DEEAFDEBC
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 7200 (seconds)
    TLS session ticket:
    0000 - e5 62 85 e1 cf 88 03 e1-d7 b8 33 bd c1 24 66 7d   .b........3..$f}
    0010 - 76 ea e4 38 9f 8c 13 47-1c 12 c3 f1 cb f8 ef 6a   v..8...G.......j
    0020 - 51 a6 3d 81 da 13 00 ac-8f e4 26 a1 90 1b 57 7b   Q.=.......&...W{
    0030 - 20 65 90 c0 98 c4 73 2a-b7 09 d9 86 e9 98 e0 de    e....s*........
    0040 - 59 f2 2e cd cc f4 16 4b-e9 6d 05 91 a2 32 0e 65   Y......K.m...2.e
    0050 - 6a f0 4a be 20 51 e0 63-bd 81 b0 a3 30 5a 21 55   j.J. Q.c....0Z!U
    0060 - 70 54 27 2d 4a 66 c1 c1-5c e5 dd 18 b8 4c c7 41   pT'-Jf..\....L.A
    0070 - fc 53 47 e2 c2 43 81 e7-6f 67 8e fd 3b 59 80 c0   .SG..C..og..;Y..
    0080 - 4f 00 94 f2 db 16 41 01-9f 47 6f 5c 31 ce ec a0   O.....A..Go\1...
    0090 - 8b fa 18 d0 4d b2 31 ab-34 9f 9e d6 c2 ef 7a 2b   ....M.1.4.....z+
    00a0 - 1e e1 d1 89 d7 43 8e ff-33 26 50 1d 10 fb 50 ca   .....C..3&P...P.
    00b0 - 15 bd 29 8d 43 cc 07 b8-ef 68 f4 6e 52 38 ed 29   ..).C....h.nR8.)

    Start Time: 1714982970
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: no
    Max Early Data: 0
---
read R BLOCK
read from 0x8000a50a0 [0x8000aaca3] (5 bytes => 5 (0x5))
0000 - 17 03 03 00 fa                                    .....
read from 0x8000a50a0 [0x8000aaca8] (250 bytes => 250 (0xFA))
0000 - 1c 01 9d b4 03 20 03 16-25 4b 44 57 2d 90 d0 7a   ..... ..%KDW-..z
0010 - 7b bc 14 aa de 80 ea 81-45 24 88 c2 56 04 2a f9   {.......E$..V.*.
0020 - 6b 46 ad d6 f4 08 30 7a-e9 74 c0 df 37 dc 0c 56   kF....0z.t..7..V
0030 - 20 56 6f 77 06 70 d9 15-ea ec 21 98 af 2a a6 31    Vow.p....!..*.1
0040 - 7f 33 35 56 32 c4 25 a3-12 03 3f bf c0 a2 b1 54   .35V2.%...?....T
0050 - 75 79 3e 3a 75 2e 47 d9-21 21 8b d3 a4 cd da 99   uy>:u.G.!!......
0060 - c8 f2 4c 6a 00 1f fc 97-48 a1 9d d6 37 d5 cd cb   ..Lj....H...7...
0070 - 3e 6c 89 18 57 8a b6 b8-41 67 39 fc 9a 32 0d 13   >l..W...Ag9..2..
0080 - 42 21 74 4d 0f e8 91 a6-46 eb cb 1e 1a b1 6d 1a   B!tM....F.....m.
0090 - cd 20 fe de 78 9d ca 2a-72 87 85 77 27 68 79 a6   . ..x..*r..w'hy.
00a0 - 95 50 7d 0f c4 e8 34 20-1c c3 51 58 29 8e bb a3   .P}...4 ..QX)...
00b0 - 97 49 c9 9a b0 5d 35 9f-37 ab 87 1d ba d4 01 ab   .I...]5.7.......
00c0 - ee 06 7c 92 b5 f2 b4 69-4d dc ba 70 35 80 81 24   ..|....iM..p5..$
00d0 - 4d 0f 83 da 7b b6 54 74-93 f9 6c 16 f4 2f 89 b7   M...{.Tt..l../..
00e0 - 10 15 91 50 9c e6 dc 33-8d 11 8a d9 f0 ed 00 ef   ...P...3........
00f0 - 61 e2 2b 7b 1c fa 5e 29-0c cf                     a.+{..^)..
---
Post-Handshake New Session Ticket arrived:
SSL-Session:
    Protocol  : TLSv1.3
    Cipher    : TLS_AES_256_GCM_SHA384
    Session-ID: 9C32B2A7EDDFE6BFD40F918D21D68589DF8FDDF39B16F045E7B28D28806C6B87
    Session-ID-ctx:
    Resumption PSK: 822E14B661C1D451C059741908C345DE348CF4984BE0F9463A8F7E27EA84177673EBB98972EF790B93070B2AC45F6767
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 7200 (seconds)
    TLS session ticket:
    0000 - e5 62 85 e1 cf 88 03 e1-d7 b8 33 bd c1 24 66 7d   .b........3..$f}
    0010 - aa 50 3f 2f ef f9 7e 83-be 9a 74 10 0b f3 28 eb   .P?/..~...t...(.
    0020 - a4 e6 ff c3 46 75 50 17-1f 7f 32 8b cc 60 85 36   ....FuP...2..`.6
    0030 - 9d 1a b3 26 cc 16 f5 9f-8f 04 64 d2 62 30 5b 34   ...&......d.b0[4
    0040 - 38 2c 5d ff 1d d7 0b d0-c7 89 8a 4a bc 97 e0 39   8,]........J...9
    0050 - a7 ed cd 6b 89 9d 15 81-77 3b 5b 57 e5 39 96 7c   ...k....w;[W.9.|
    0060 - 41 e6 7f a2 d4 da c4 f4-34 a0 a4 a8 98 2f 73 d2   A.......4..../s.
    0070 - 0e 88 07 0b 86 7e 57 9d-cd b8 79 93 47 c6 88 03   .....~W...y.G...
    0080 - 31 f0 6a fe 28 54 66 de-25 06 45 95 eb e5 47 2b   1.j.(Tf.%.E...G+
    0090 - 57 aa 7b 0d 9f 3d d2 cd-74 2f 9c 92 ae 7c 36 6c   W.{..=..t/...|6l
    00a0 - 47 95 0e 6c 69 48 d1 ba-fe 72 01 2b 68 24 af b5   G..liH...r.+h$..
    00b0 - c6 ed 1c 14 9e f1 fd 0d-5e 92 bb 95 26 7e 61 85   ........^...&~a.
    00c0 - 34 ec df ad e1 d2 17 8c-08 cd cc d1 76 65 34 6e   4...........ve4n

    Start Time: 1714982970
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: no
    Max Early Data: 0
---
read R BLOCK

write to 0x8000a50a0 [0x8001b4ec3] (23 bytes => 23 (0x17))
0000 - 17 03 03 00 12 04 0d 6f-ce 78 45 69 8d 6e b8 5c   .......o.xEi.n.\
0010 - a2 23 90 91 15 d0 44                              .#....D

5、HTTPS 开源库之 libcurl 的使用

libcurl 是 HTTP 数据交互最常用的开源库,可以很轻松地发送和处理 HTTP 数据。

curl官网: https://curl.se/ ,开发指导: https://curl.se/libcurl/c/example.html 和 https://curl.se/libcurl/c/libcurl-tutorial.html ,libcurl下载: https://curl.se/download.html

下载后使用 configure 配置,要启用 ssl,还需下载安装 openssl: TLS/SSL and crypto library (github.com) ,执行 make 和 make install 即可生成库和相关头文件,然后进行开发,具体配置编译过程,篇幅原因不做介绍,网上有很多资料。这边讲两个常用的发送 GET 和 POST 报文的代码例子:

HTTPS GET请求示例

#include <stdio.h>
#include <curl/curl.h>

static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) {
    size_t totalSize = size * nmemb;
    memcpy(userp, contents, totalSize); // 这边就是readBuffer传递进来的参数,收到的数据会持续回调,需要控制写入和缓存的大小
    return totalSize;
}

int main() {
    CURL *curl;
    CURLcode res;
    char readBuffer[102400]; // Adjust buffer size as needed

    curl_global_init(CURL_GLOBAL_DEFAULT);
    curl = curl_easy_init();
    if(curl) {
        curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/api/data");
        // curl_easy_setopt(curl, CURLOPT_HTTPHEADER, "headers: custom_headers"); // 可以自己写首部数据
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, readBuffer);
        
        // 开启ssl认证
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L);
        
        res = curl_easy_perform(curl);
        if(res != CURLE_OK) {
            fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
        }
        else {
            printf("GET Response: %s\n", readBuffer);
        }
        
        curl_easy_cleanup(curl);
    }
    curl_global_cleanup();
    return 0;
}

HTTPS POST请求示例

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>

static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) {
    size_t totalSize = size * nmemb;
    memcpy(userp, contents, totalSize); // 这边就是readBuffer传递进来的参数,收到的数据会持续回调,需要控制写入和缓存的大小
    return totalSize;
}

int main() {
    CURL *curl;
    CURLcode res;
    char readBuffer[102400];
    const char *postFields = "body data, abcdefg..."; // 要发送的主体数据

    curl_global_init(CURL_GLOBAL_DEFAULT);
    curl = curl_easy_init();
    if(curl) {
        curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/api/data");
        // curl_easy_setopt(curl, CURLOPT_HTTPHEADER, "headers: custom_headers"); // 可以自己写首部数据
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, readBuffer);
        
        // 设置要发送的数据
        curl_easy_setopt(curl, CURLOPT_POST, 1L);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postFields);
        
        // 开启ssl认证
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L);
        
        res = curl_easy_perform(curl);
        if(res != CURLE_OK) {
            fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
        }
        else {
            printf("POST Response: %s\n", readBuffer);
        }
        
        curl_easy_cleanup(curl);
    }
    curl_global_cleanup();
    return 0;
}

附录一、URL 编码和 BASE64 编码

URL 编码,它的原理是通过在对应字符的十六进制前面加个百分号’%'来实现,比如取地址符‘&’对应十六进制为 0 x 26,加个百分号,那它编码后就是"%26",变成 3 个 ASCII 字符,ACK 符 0 x 06,编码后就是"%06"三个字符,再举个中文的例子:

GET /search?q=你好HTTP世界 HTTP/1.1
Host: example.com
...

// 转码后

GET /search?q=%E4%BD%A0%E5%A5%BD%20HTTP%E4%B8%96%E7%95%8C HTTP/1.1
Host: example.com
...

这种把特殊字符表示为%开头的字符序列,又叫做百分号编码。现在有的用 BASE 64 url 编码(BASE 64 编码的一种特例)代替了 URL 编码。

BASE 64 编码,是另一种常见的编码,它不仅可应用于首部,也常用于主体部分,它可以解决各系统以及传输协议中二进制不兼容的问题,比如以前的邮件传输协议只支持 ascii 码,再比如当一些不可见字节流在网络上传输时,可能会经过老的路由设备,这些设备对于不可见字符的处理可能出现异常,这是不利于传输的。所以就先把数据进行 BASE 64 编码后变成 ASCII 码可见字节,再进行传输。

它的编码原理是从 ASCII 码中取 64 个字符==(A~Z, a~z, 0~9,+,/)(见下表),外加一个等号"="==,作为编码字符,再给它们加上索引,这样就可以按索引来对任意数据进行编码。
在这里插入图片描述

具体的方法就是,把一个字节中高 6 位的数据取出来,然后在前面补两个位的 0,组成一个新字节(8 bit),新的字节这样最小值为 0,最大值为 0011 1111,即 63,刚好对应编码表,就根据编码表来取对应的字符,比如 63 就是字符’/'。但是取了 6 位,还剩下 2 位还没有处理,这时就需要补两个字节的 0,因为补上后就剩下 18 个比特的位没有取,刚好可以分 3 次取完,最终会变成一个四字节的字符串。

举例:如果一个数据有三个字节,那从高位开始依次取 6 位,取到第 3 个次(18 位)时,就会剩下最后 6 位的数据,刚好可以按照规则补 2 个位的 0,最后凑成 4 个字节,这样每三个字节的数据可以刚好编码成四个字节的 BASE 64 数据。

如果字节数少于 3 个或不是 3 的倍数,那就在数据的最后补上 0,凑足 3 的倍数。然后由于这个 0 处在结尾的位置时,为了避免解码时产生歧义,对应的字符使用一个专有字符等号‘=’来表示结尾,其他的位置如果是 0,那还是需要使用索引表对应的字符’A’。

因此,所有 base 64 编码后的数据字节数一定是 4 的倍数,举个例子:

三个字节:

在这里插入图片描述

两个字节:

状态数据二进制十进制 (索引)ASCII 字符
转换前10101101,10111010AD BA
用 0 补齐数据10101101,10111010,00000000
转换后00101011, 00011011 ,00101000 ,000000000 x 2 B 0 x 1 B 0 x 28 0 x 0043 27 40 0r b o =

Base 64 URL 编码

base 64 url 编码是专为 URL 设计的 Base 64 变种,它将 Base 64 中的"+“替换为”-“,将”/“替换为 “_”,以避免在 URL 中引起解析问题,同时移除了标准 Base 64 中的等号”="填充符,因为在 URL 或 Cookie 中等号和分号等有特殊含义。

附录二、加密算法分类

可分为对称算法和非对称算法。

对称加密算法

加密和解密使用相同密钥的算法(加密Key=解密key),对称密钥算法又分为分组密码 (Block Cipher)和流密码(Stream Cipher)。

分组密码(Block Cipher): 分组密码算法将明文数据划分成固定长度的数据块(block),每个块独立进行加密处理。块的大小是固定的,常见的有64位、128位等,例如DES使用64位块,而AES可以使用128、192或256位块。由于加密块是固定的,对于不足一个块的明文,通常需要进行填充,填充方法可以填 0 或者需要填充的长度本身的值等。

流密码(Stream Cipher): 流密码则是对数据流进行连续处理,每次加密一位或一个字节的数据。它通过密钥生成一个伪随机的密钥流(keystream),然后将此密钥流与明文数据流进行逐位异或(XOR)操作以实现加密,解密时使用同样的密钥流进行反向操作。流密码的一个关键优势是加密和解密操作都非常简单且快速,适用于硬件实现和低功耗设备,但设计不当容易受到重放攻击和密钥重复使用攻击。

常用的对称加密算法包括:

DES (Data Encryption Standard,数据加密算法) 
3DES (Triple Data Encryption Algorithm,三重数据加密算法)
AES (Advanced Encryption Standard,高级加密标准,又称Rijndael加密法) 
PBE (Password-based encryption,基于密码验证)
RC2、RC4、RC5(来自Rivest Cipher 4的缩写)
SM1、SM4、SM7、祖冲之密码(zuc)(都是国密算法),SM1和SM7对外是不公开的,想要调用的话,需要通过加密芯片的接口才可以

优点:加密速度快,便于硬件实现和大规模生产;

缺点:需要保障密钥安全;无法用来签名和抗抵赖;

非对称加密

非对称密码体制也叫公开密钥密码体制、双密钥密码体制。

其原理是加密密钥与解密密钥不同,它会形成一个密钥对(公钥/私钥),对外公布的成为公钥,私钥则由自己保存,别人只能通过公钥给数据加密再发给你,过程中第三方无法通过其他手段来解密数据,到自己手上通过密钥才能解密。

常用算法:
RSA、Elgamal、Elgamal(离散对数)、Rabin、D-H、ECC(椭圆曲线加密算法),
还有国密算法(SM2,SM9,SM3(哈希算法))
使用最广泛的是RSA算法,Elgamal是另一种常用的非对称加密算法。

优点:密钥分配,不必保持信道的保密性;可以用来签名和防抵赖。

哈希算法

哈希算法不属于加密算法,属于校验算法,它无法通过可逆方式解密,比如对一个文件进行哈希处理,就能通过哈希值确认这个文件的完整性,但无法通过哈希值还原这个文件的内容。常见HASH算法有:MD5、SHA1、SHA256、SHA512、NTLM等。

除了哈希算法,还有其他的包括校验和、CRC 校验、奇偶校验、海明码等校验方法。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值