TG WS Proxy代码剖析:MTProto混淆握手全解读——dd/ee密钥与64字节init包的AES-CTR解密
TG WS Proxy代码剖析MTProto混淆握手全解读——dd/ee密钥与64字节init包的AES-CTR解密TG WS Proxy 是一款运行在本地的 MTProto 代理服务器把 Telegram Desktop 的流量改走 WebSocket 通道从而绕开部分加载卡顿。本文带你拆解它的握手代码dd/ee两种密钥的来历、64 字节 init 包的逐段结构以及代理如何用 AES-CTR 解密并验证客户端的完整流程。 TG WS Proxy 是什么本地 MTProto 代理的架构一句话概括客户端连上本地代理后代理拦截 MTProto 混淆连接把数据解密→重新加密后转发给 Telegram 的 WebSocketkws*.web.telegram.orgWebSocket 不通时再依次回退到 Cloudflare 代理、CF Worker 或直接 TCP 转发。整个握手与加解密的入口都在 proxy/tg_ws_proxy.py 中每连接一条客户端就派生一个异步任务执行_handle_client依次完成读 init 包 → 验证握手 → 建加密上下文 → 重加密桥接四步。️ dd 与 ee两种密钥从哪里来服务启动时代理会生成两条连接链接见_run前缀链接格式含义ddsecretdd32位hex标准 MTProto 混淆直连eesecretee32位hex域名的hexFake TLS 伪装 MTProto 混淆两者共用同一个 32 位十六进制16 字节的secret区别只在握手的第一段长什么样。dd 密钥裸 MTProto 混淆连接开启端点收到第一个字节后如果不是 TLS 记录头就直接按 MTProto 混淆模式读满 64 字节 init 包_read_client_init。这是 Telegram 官方 MTProto 代理的标准形态。ee 密钥Fake TLS 伪装握手配置了--fake-tls-domain后客户端会先发一个伪装的 TLS ClientHello验证端用HMAC-SHA256(secret, 抹零random后的ClientHello)的前 28 字节比对client_random末 4 字节还原出带时间戳±120 秒容差见verify_client_hello回应一个构造好的 ServerHelloserver_random也是 HMAC 派生见build_server_hello之后的 64 字节 init 包被包在 TLS 应用数据记录0x17里传输见 fake_tls.py。这样在链路上抓包看到的就是TLS 连接 加密数据更难被特征识别。验证不通过则直接回 301 跳转把非 TG 流量踢到伪装域名。 64 字节 init 包的结构拆解所有偏移常量集中在 proxy/utils.py一次看全偏移长度内容0–78随机填充8–3932prekey本次连接随机的预密钥40–5516ivAES-CTR 的 16 字节初始向量56–594协议标签解密后才可见60–612DC 索引小端有符号负数 媒体 DC62–632随机填充三个协议标签同样定义在 proxy/utils.pyef ef ef ef0xEFEFEFEF— abridged 协议ee ee ee ee0xEEEEEEEE— intermediate 协议dd dd dd dd0xDDDDDDDD— padded intermediate 协议注意56–61 这段在线路上是密文必须用 AES-CTR 解开才能看到标签和 DC。 AES-CTR 解密代理如何验证客户端核心逻辑只有几十行全部在_try_handshake取材料prekey init[8:40]iv init[40:56]推密钥key SHA256(prekey secret)——每次连接 prekey 都是随机 32 字节密钥永不上链路且必须持共享 secret 才能算出全量解密用AES-128-CTR(key, iv)解整 64 字节验证标签明文字节 56:60 必须命中三个协议标签之一否则判定错误密钥或错误协议丢弃连接读 DC字节 60:62 小端取有符号整数绝对值即数据中心编号负号表示媒体 DC。AES-CTR 的加密与解密是同一操作对称密钥流所以代码里解密器直接复用了加密器proxy/_aes.py。依赖兜底没有 cryptography 也能跑proxy/_aes.py 是个垫片桌面/Docker 环境优先用cryptography库路由器、嵌入式这类装不了 Python 包的环境自动回退到 ctypes 直调系统 OpenSSL 的EVP_aes_*_ctr接口第 17–64 行支持 128/192/256 位密钥。 反向密钥与重加密桥握手验证通过后代理还要建四路加密上下文_build_crypto_ctx封装在 bridge.py 的CryptoCtx中方向密钥材料解客户端decSHA256(prekey secret)iv 取[40:56]回客户端enc把prekey‖iv整段字节翻转后再SHA256(前32字节 secret)iv 取翻转后的后 16 字节发 Telegramenc直接用 relay init 的[8:40]/[40:56]无 secret收 Telegramdec同样取 relay init 的[8:56]翻转后拆 3216发往 Telegram 的 relay init 是怎么造的_generate_relay_init生成一包标准 MTProto 混淆init不掺 secret并做了三处防误判过滤首字节避开0xEF协议保留字节前 4 字节避开HEAD/POST/GET/eeee/dddd/TLS 记录头等保留开头字节 4:8 避开全零的00 00 00 00续传标记。最后 8 字节标签 DC的密文是用 AES-CTR手动截取密钥流异或构造出来的保证 Telegram 解开后看到正确的协议标签与 DC 索引。双向重加密bridge_ws_reencryptbridge.py 里的桥接逻辑是全文最点睛的部分两条协程互相对称上行客户端密文 → clt_dec 解密 → tg_enc 加密 → 发往 WS 下行WS 密文 → tg_dec 解密 → clt_enc 加密 → 回客户端即客户端侧dd/ee 密钥域与 Telegram 侧标准混淆域各说各的密码代理在中间当翻译官。配合 MsgSplitter 把连续 TCP 流按 MTProto 包边界切开abridged 按 1/4 字节头长计算intermediate 按 4 字节长度头计算每个包单独成 WebSocket 帧发送避免大包粘包。 核心源码文件导航proxy/tg_ws_proxy.py — 主入口握手验证、密钥链接生成、DC 路由与回退proxy/bridge.py — 四路加密上下文、消息切分、双向重加密桥proxy/_aes.py — AES-CTR 垫片cryptography / OpenSSL 双实现proxy/fake_tls.py — ee 密钥的伪 TLS 验证与应答proxy/utils.py — 握手包偏移与协议标签常量proxy/raw_websocket.py — 自研 WebSocket 客户端含 302 重定向跟随使用文档docs/EN/README.md、docs/EN/FakeTlsNginx.md、docs/EN/CfWorker.md 获取源码git clone https://gitcode.com/gh_mirrors/tg/tg-ws-proxy总结TG WS Proxy 的握手设计可以浓缩成三个要点密钥分层dd走标准混淆ee先过一层 HMAC 伪 TLS 再进混淆抓包特征各不相同密钥不上线AES 密钥永远由随机 prekey 共享 secret经 SHA256 现场推导链路上只暴露可丢弃的随机材料双域重加密代理持有客户端域与 Telegram 域两套独立的 CTR 密钥流逐块解密再加密让两端协议互不感知中间人。读懂这套64 字节 init 包 AES-CTR的握手再去看 Telegram 任何 MTProto 混淆代理的实现都会顺畅许多。创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

cangjie_runtime std.unittest.mock 构造函数全解析:mock\<T>、mock\<T>(StubMode) 与 spy\<T> 的用法与实现

cangjie_runtime std.unittest.mock 构造函数全解析:mock\<T>、mock\<T>(StubMode) 与 spy\<T> 的用法与实现

编程语言语言运行时标准库垃圾回收并发编程 【免费下载链接】cangjie_runtime 仓颉编程语言运行时与标准库。 项目地址: https://gitcode.com/Cangjie/cangjie_runtime 点击查看 免费下载 本文以仓颉标准库单元测试 mock 框架(std.unittest.mock&#x…

2026/10/15 2:16:17 阅读更多 →
2S串联电芯主动均衡方案:基于MP2642与STM32的BMS设计

2S串联电芯主动均衡方案:基于MP2642与STM32的BMS设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 2:15:17 阅读更多 →
单片机C库运行时:libspace、多任务重入与中断安全实战

单片机C库运行时:libspace、多任务重入与中断安全实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 2:15:17 阅读更多 →

最新新闻

从零开发聚合9大视频网站的桌面App:技术选型与发布运营复盘

从零开发聚合9大视频网站的桌面App:技术选型与发布运营复盘

前阵子我在一个技术交流群里发了句感叹:“现在做桌面应用,是不是有点逆潮流?”结果有个朋友直接回我:“你做一个有用的桌面工具试试,用户在乎的是好不好用,又不是你用什么平台。”我当时不以为然&#xff0…

2026/10/15 2:47:27 阅读更多 →
FastAPI响应模型设计与优化实战

FastAPI响应模型设计与优化实战

1. FastAPI响应模型参数解析在FastAPI开发中,响应模型参数是构建API契约的重要组成部分。它们不仅定义了接口返回数据的结构和类型,还直接影响着API文档的自动生成和客户端的数据校验。作为使用FastAPI三年多的开发者,我发现很多团队对响应模…

2026/10/15 2:47:27 阅读更多 →
Lombok失效排查:IDE标红但编译通过的原因与解决

Lombok失效排查:IDE标红但编译通过的原因与解决

先记住这个场景:项目跑得好好的,代码里到处是Data、Getter、Setter,结果某一天打开 IDE,满屏“红波浪线”,提示找不到getXxx()、setXxx()方法。你第一反应是哪里写错了,可把代码翻来覆去看了好几遍&#xf…

2026/10/15 2:47:27 阅读更多 →
UE4纹理资产创建全流程:从PBR贴图到材质装配

UE4纹理资产创建全流程:从PBR贴图到材质装配

做项目的时候,美术最常跟我念叨的一句话就是“这材质还差一张好贴图”。在虚幻4(UE4)里,纹理资产是所有材质表现的基石,没有纹理,模型再精密也只是一块带着基础着色的素模。这几年不管是自己做Demo还是带项…

2026/10/15 2:47:27 阅读更多 →
从“应该学”到“正在做”:用AI陪练两周搭建微型知识图谱

从“应该学”到“正在做”:用AI陪练两周搭建微型知识图谱

我收藏过的知识图谱入门资料,少说也有七八篇,真正打开看完的,不超过两篇。“我应该学知识图谱”这个念头在我脑子里盘旋了大约两年,直到我换了个思路——把 AI 当成学习陪练,而不是搜索引擎、不是网课老师,…

2026/10/15 2:47:27 阅读更多 →
从源码编译GMSSL:国密算法支持与HTTPS链接调试实战

从源码编译GMSSL:国密算法支持与HTTPS链接调试实战

1. 从源码到动态库:为什么选择自己编译GMSSL很多人第一次接触国密算法开发时,第一反应是找现成的二进制包或者系统自带的包管理器直接安装。这个思路在大多数场景下没问题,但一旦涉及国密算法,情况就完全不一样了。GMSSL作为国内广…

2026/10/15 2:46:27 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →