加密扩展记录 37B(含头口径):Go TLS 栈形态特征的适用域与配对勘误
摘要
TLS 1.3 握手中,服务端在 ServerHello 之后发送加密的 EncryptedExtensions(EE)。本文分两个观测环境陈述直证数据并修正一处早期配对错误:(a) 本地测试台批次 ------认证会话与 Go 标准栈 decoy 直连的首条加密记录同值(记录长度 37,含 5B 记录头口径,载荷 32),17 次认证回放零例外;同批认证路径 ServerHello 记录 127(含头),与标准栈同值------即本地环境中 SH+EE 组合不能 区分认证路径与 Go-decoy;(b) 真实公网批次 ------认证路径首条加密飞行与真站直连同构(载荷 2032--2034 vs 2032--2033,区间重叠),同样无差分。早期文档曾以"SH=1215 + EE=37B"作为组合判据,经复核该组合从未在同会话出现 (1215 属真实公网批次、37 属本地批次,两者不同环境),组合与随之的信度声明一并废止。37B 的有效语义收敛为:目标站点 TLS 栈的 EE 记录形态指纹(Go 系 32/37 vs 非 Go 栈 4477 量级),用于栈型识别与基线一致性核查,不用于认证路径判别。本文仅陈述实测数据与勘误,不含修改建议。
受用范围声明(先读):直接测量仅覆盖 Xray v26.3.27(主观测批次版本,版本==语义);其余版本未直接测量。现官方最新 v26.7.28 发布(2026-07-28)早于观测日(2026-08-31),关键判据(形态族同构)已于 2026-09-01 在 v26.7.28 复核复现,其余条目与未纳入观测和补验的版本(含 v26.4~v26.7 及 2026-09-01 之后发布的版本)未验证。"恒定"仅指本工作观测的稳定复现值。
口径声明:本文"37/127/401/102/58/144/24"为旧观测档案口径(含 5B 记录头的记录总长),对应载荷 32/122/396/97/53/139/19;"2032--2034/1210/445/57/19"为新解析器载荷口径。两套口径换算关系:含头 = 载荷 + 5(CCS 记录 6 vs 1 自证)。
1 背景与原理
- TLS 1.3 握手 s2c 顺序:ServerHello(明文记录)→(服务端加密飞行:EE → Certificate → CertificateVerify → Finished,各为独立记录或合并飞行,取决于实现);
- Go 标准栈把加密握手消息逐条独立成记录 ;REALITY 认证路径的 fork 栈在真实公网批次中观测到合并飞行形态(单条 2032--2034);
- EE 记录长度由协议协商内容(应用层协议协商、版本选择等)+ 实现的分片/加密方式决定;
- 本地批次(decoy=Go 标准栈):认证与 decoy 直连形态同值(127/37/401/...);真实公网批次(decoy=cloudflare):认证与真站直连形态同构(1210/2032-4/445/57)。
2 方法
- 构造携带有效认证数据的 ClientHello(同源样本重复回放),另以无效认证数据会话取"真站直连"对照(回落透传路径,端到端握手直达真实站点);
- 捕获 s2c 完整记录序列(类型/长度);
- 提取 ServerHello 记录与首个加密记录(CCS 之后)长度,统计重复会话稳定性;
- 对照环境:本地 Go 标准栈服务、模拟非 Go 栈(OpenSSL 形态)、真实公网大站(BoringSSL 等)。
#mermaid-svg-4PxaGaLgUv396iZo{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-4PxaGaLgUv396iZo .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-4PxaGaLgUv396iZo .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-4PxaGaLgUv396iZo .error-icon{fill:#552222;}#mermaid-svg-4PxaGaLgUv396iZo .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-4PxaGaLgUv396iZo .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-4PxaGaLgUv396iZo .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-4PxaGaLgUv396iZo .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-4PxaGaLgUv396iZo .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-4PxaGaLgUv396iZo .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-4PxaGaLgUv396iZo .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-4PxaGaLgUv396iZo .marker{fill:#333333;stroke:#333333;}#mermaid-svg-4PxaGaLgUv396iZo .marker.cross{stroke:#333333;}#mermaid-svg-4PxaGaLgUv396iZo svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-4PxaGaLgUv396iZo p{margin:0;}#mermaid-svg-4PxaGaLgUv396iZo .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-4PxaGaLgUv396iZo .cluster-label text{fill:#333;}#mermaid-svg-4PxaGaLgUv396iZo .cluster-label span{color:#333;}#mermaid-svg-4PxaGaLgUv396iZo .cluster-label span p{background-color:transparent;}#mermaid-svg-4PxaGaLgUv396iZo .label text,#mermaid-svg-4PxaGaLgUv396iZo span{fill:#333;color:#333;}#mermaid-svg-4PxaGaLgUv396iZo .node rect,#mermaid-svg-4PxaGaLgUv396iZo .node circle,#mermaid-svg-4PxaGaLgUv396iZo .node ellipse,#mermaid-svg-4PxaGaLgUv396iZo .node polygon,#mermaid-svg-4PxaGaLgUv396iZo .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-4PxaGaLgUv396iZo .rough-node .label text,#mermaid-svg-4PxaGaLgUv396iZo .node .label text,#mermaid-svg-4PxaGaLgUv396iZo .image-shape .label,#mermaid-svg-4PxaGaLgUv396iZo .icon-shape .label{text-anchor:middle;}#mermaid-svg-4PxaGaLgUv396iZo .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-4PxaGaLgUv396iZo .rough-node .label,#mermaid-svg-4PxaGaLgUv396iZo .node .label,#mermaid-svg-4PxaGaLgUv396iZo .image-shape .label,#mermaid-svg-4PxaGaLgUv396iZo .icon-shape .label{text-align:center;}#mermaid-svg-4PxaGaLgUv396iZo .node.clickable{cursor:pointer;}#mermaid-svg-4PxaGaLgUv396iZo .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-4PxaGaLgUv396iZo .arrowheadPath{fill:#333333;}#mermaid-svg-4PxaGaLgUv396iZo .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-4PxaGaLgUv396iZo .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-4PxaGaLgUv396iZo .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-4PxaGaLgUv396iZo .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-4PxaGaLgUv396iZo .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-4PxaGaLgUv396iZo .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-4PxaGaLgUv396iZo .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-4PxaGaLgUv396iZo .cluster text{fill:#333;}#mermaid-svg-4PxaGaLgUv396iZo .cluster span{color:#333;}#mermaid-svg-4PxaGaLgUv396iZo div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-4PxaGaLgUv396iZo .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-4PxaGaLgUv396iZo rect.text{fill:none;stroke-width:0;}#mermaid-svg-4PxaGaLgUv396iZo .icon-shape,#mermaid-svg-4PxaGaLgUv396iZo .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-4PxaGaLgUv396iZo .icon-shape p,#mermaid-svg-4PxaGaLgUv396iZo .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-4PxaGaLgUv396iZo .icon-shape .label rect,#mermaid-svg-4PxaGaLgUv396iZo .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-4PxaGaLgUv396iZo .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-4PxaGaLgUv396iZo .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-4PxaGaLgUv396iZo :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 本地批次(decoy=Go栈)
SH 127(含头) + 首EE记录 37
SH 127 + EE 37
唯余差分
真实公网批次(decoy=cloudflare)
SH 1210 + 首飞行 2032-2034(载荷)
SH 1210 + 首飞行 2032-2033
认证会话
与真站直连同构:不可分
真站直连
认证会话
与decoy直连同值:不可分
decoy直连
NST 记录:认证19 vs Go-decoy139 载荷
3 实测数据(v26.3.27)
3.1 本地批次(受控回放,认证路径)
| 项目 | 值(含头口径) | n | 环境 | 来源 |
|---|---|---|---|---|
| 认证回放首条加密记录 | 37(全数) | 17(两批 5+12) | Windows 测试台,Xray v26.3.27,decoy=本地 Go 标准栈 | 测试台回放批次记录 |
| 认证 ServerHello 记录 | 127 | 同批 | 同上 | 同上 |
| decoy 直连同两项 | 127 / 37 | 3 | 同上 | 同上 |
- 17 次零例外;认证与 decoy 直连在 SH/EE 两项同值------长度侧无法区分两路径(同批唯一已测差分在 NST:19 vs 139 载荷)。
3.2 真实公网批次(cloudflare decoy,含重复批各 5)
| 项目 | 认证(n=5+1) | 真站直连(n=5+1) | 口径 |
|---|---|---|---|
| ServerHello 记录 | 1210 | 1210 | 载荷 |
| 首个加密飞行 | 2032,2032,2032,2034,2034 | 2032,2032,2033,2033,2033 | 载荷 |
| 后续两记录 | 445 / 57 | 445 / 57 | 载荷 |
| 握手后 NST 记录 | 19(第 159--332 条) | 19(紧随握手) | 载荷 |
- 两分布区间重叠(2032--2034 vs 2032--2033),差异为密文随机填充;不存在可分离阈值;
- NST 位置差异(认证延迟出现 vs 真站即时)受会话时长差异影响(直连对照会话握手后仅 6 条记录即结束),不能归因于 REALITY,不作判据主张。
3.3 对照与非 Go 栈观测
| 对照源 | ServerHello 记录 | 首条加密记录 | 备注 |
|---|---|---|---|
| 本地 Go crypto/tls | 127(含头) | 37(含头) | 与本地认证同值 |
| 真实大站(BoringSSL 形态,观测记录) | --- | 4477 量级 | 单一站点;受证书/ECH 影响;口径未复核(未验证) |
| 微软 decoy 批次 | 1215(含头) | 未获得(会话未完成) | 与 cloudflare 批同值之机理未验证,不作解释 |
3.4 判别边界(修正后)
- 37B(含头)/32B(载荷)仅是 Go 系栈的 EE 记录形态:对"认证 vs Go 栈 decoy/真站"无判别力(3.1/3.2 同值证据);对"Go 栈 vs 非 Go 栈"有形态区分(4477 量级对照,站点多样性有限);
- 早期"SH=1215 + EE=37 → 认证专属"的组合废止:1215 与 37 来自不同环境的两批观测,从未在同会话共现(同会话实测为 127+37 或 1210+2032-4);
- 相应信度数值(0.90/0.55/0.85)为旧语义标定,随组合废止而失效(新语义未标定);
- 单判据不定案;本文特征仅作栈形态基线核查输入。
4 局限
- 直接测量仅 v26.3.27(受用范围见声明);
- EE 记录长度依赖协商内容(应用层协议、版本等)与实现分片方式------配置敏感性未验证;
- 非 Go 栈对照来自单一观测记录,多样性有限;
- 真实公网认证侧样本 n=6、直连 n=6,扩样待部署期;
- 网络侧无解密时,EE 明文内容不可见,本文判据均为记录层长度(不需要解密)。
未验证项清单
| 项 | 状态 | 验证方法 |
|---|---|---|
| 新语义下的任何组合信度 | 未标定 | 扩样+独立评估,方法已知 |
| 微软批次首加密记录与真站关系 | 未获得(会话未完成) | 同拓扑重采,方法已知 |
| 4477 量级观测的口径 | 未复核 | 原始捕获重解析,方法已知 |
| EE 长度对配置项的敏感性 | 未验证 | 配置矩阵重采,方法已知 |
5 参考文献
- RFC 8446 ------ TLS 1.3(EncryptedExtensions;记录层);
- xtls/reality 源码快照(观测时点 HEAD
9234c77;f07c896/ebbbf46); - Go 标准库 crypto/tls(对照栈);
- 配套整合文档:真实 TLS 1.3 站点与认证伪装的对照实验(实验 D/A 系列)。
附录:关联工具功能与源代码锚点
| 功能名 | 用途 |
|---|---|
| 会话捕获器 | 双向字节记录与记录序列解析 |
| 认证回放器 | 同源 CH 重复回放认证会话 |
| 回落透传对照器 | 无效认证数据会话获取真站直连 flight |
- 源代码锚点(公开可查):xtls/reality
9234c77;xray-core5e245b08;Go crypto/tls;RFC 8446。 - 受众边界:仅向部分网络安全研究人员开放;身份确认+授权+合规;不含修复建议与攻击性用途。
- PoC 形态:捕获→提取 SH/首条加密记录长度→按口径与基线比对,产物为长度分布表。
- 本附录及正文不含内部工程脚本、路径与实验编号。
勘误记录:本文档早期版本含"SH=1215+EE=37 组合判据"表述,经重复实验(§3.2)证实该组合从未同会话出现,已删除;相关信度同时废止。