☰
手机上的MTProto加密:tg-ws-proxy-android的AES-256-CTR、Secret Key与消息拆分机制
2026/10/4 4:13:41 网站建设 项目流程

手机上的MTProto加密:tg-ws-proxy-android的AES-256-CTR、Secret Key与消息拆分机制

【免费下载链接】tg-ws-proxy-androidAndroid-форк популярного приложения Flowseal - tg-ws-proxy - локальный прокси-сервер MTProto с проксированием CF или без для частичного обхода проблем загрузки Telegram项目地址: https://gitcode.com/gh_mirrors/tg/tg-ws-proxy-android

在 Android 手机上,tg-ws-proxy-android 是一个把 Telegram 的 MTProto 加密流量重定向到 WebSocket 通道的本地 MTProto 代理(MTProto proxy)。它的核心安全机制是:用Secret Key(密钥)参与 AES-256-CTR 密钥流推导,并用消息拆分器(MsgSplitter)把连续字节流还原成一条条 MTProto 消息。这篇文章带你从零看懂这套机制到底怎么工作——无需数学基础,也能理解手机代理中的加密逻辑 🔐。

Telegram 客户端 │ 1. 64字节握手包(含 prekey + IV,用 AES-256-CTR 加密) ▼ 手机本地 MTProto 代理(tg-ws-proxy-android,端口 1443) │ 2. Secret Key 验证 → 建立 4 条 AES-256-CTR 密钥流 │ 3. MsgSplitter 把字节流拆分为单条 MTProto 消息 ▼ CloudFlare WebSocket / 直连 → Telegram 数据中心(DC1~DC5)

Secret Key:MTProto 代理的"门禁密码"

MTProto 代理(MTProto proxy)与普通 HTTP 代理最大的区别:它必须能解密握手包的第一帧,才能识别客户端要连哪个数据中心(DC ID)。这个"钥匙"就是 Secret Key。

  • 它是一个32 位十六进制字符串(16 字节),由应用自动生成或手动填写;
  • 在 Telegram 中配置代理时,密钥带前缀,例如dd<secret>(ee<secret><domain>用于 FakeTLS 伪装模式);
  • 代理端会先校验:长度必须是 32、且必须是合法 hex,否则直接拒绝。

相关源码:

  • 密钥默认值与全局状态:src/config.rs#L132-L134
  • 密钥校验(32 位 hex 才接受):src/lib.rs#L278-L289
  • 带dd/ee前缀的完整密钥生成:src/lib.rs#L297-L308

Android 端在首次启动时会自动生成密钥并保存到本地配置:

  • 自动生成逻辑:app/src/main/java/com/amurcanov/tgwsproxy/ui/ConnectionTab.kt#L75-L104
  • 持久化存储:app/src/main/java/com/amurcanov/tgwsproxy/SettingsStore.kt#L89

⚠️安全提示:任何拿到你 Secret Key 的人都能"伪装成你的 Telegram 客户端"接入本地代理。密钥不要截图发到群里,更不要写入公开配置。

64字节握手:AES-256-CTR 密钥流是怎么推导的

客户端连上本地端口(默认 1443)后,会先发送一个64 字节的握手包,其内存布局是固定常数(定义在 src/config.rs#L24-L39):

偏移长度内容
0–78 字节跳过区(skip)
8–3932 字节客户端解密密钥 prekey
40–5516 字节IV(初始向量)
56–594 字节MTProto 协议标识(proto tag)
60–612 字节数据中心编号(DC ID,负数表示媒体 DC)

代理端验证流程(源码见 src/proxy.rs#L1671-L1705):

  1. 取 prekey + Secret Key 做 SHA-256,得到 32 字节 AES-256 密钥;
  2. 用该密钥 + IV 构造AES-256-CTR密码器,对手握包做 XOR 解密;
  3. 检查解密出的 proto tag 是否为0xEFEFEFEF/0xEEEEEEEE/0xDDDDDDDD之一——如果密钥错误,这里必然失败,连接直接被丢弃并计入bad handshake统计;
  4. 从第 60 字节读出 DC ID:正数连普通 DC,负数连媒体 DC,≥10000自动转入测试 DC。

密钥正确后,代理会为这条连接建立4 条独立的 AES-256-CTR 密钥流(见 src/proxy.rs#L1742-L1770):

上行方向:clt_dec(解密客户端) ──XOR──▶ tg_enc(加密后发给 Telegram) 下行方向:tg_dec(解密 Telegram) ──XOR──▶ clt_enc(加密后发回客户端)

为什么叫 CTR 模式?AES-256-CTR 把分组密码变成了"密码本":密钥+IV 生成一条无限密钥流,加解密都是 XOR,速度快、可随机访问,特别适合代理这种需要逐字节实时转换的场景。每条流的实现是一个TrackedStream,它记录已处理字节数,支持"克隆状态"以便分支处理(src/crypto.rs#L12-L56)。

💡 通俗理解:代理不是"破译"了 Telegram 的加密,而是替 Telegram 客户端做了一层等价转换——把 MTProto 加密的字节流原封不动地"搬运"到 WebSocket 通道,自己只负责握手验证与字节重加密。

消息拆分机制:为什么代理必须"读懂"MTProto

字节流搬运有个小麻烦:一个 TCP 包(或 WebSocket 帧)里可能粘连着多条 MTProto 消息,也可能一条消息被截断成两截。代理不能盲目整块转发,必须按 MTProto 格式把流精确切割成独立消息,否则下游服务无法解析。这就是MsgSplitter的职责(src/crypto.rs#L74-L260)。

它的工作方式是"影子解密":边接收密文,边用 AES-256-CTR 密钥流解密出明文副本,再在明文上读取每条消息的长度头:

格式proto tag长度头读取方式
精简格式(abridged)0xEFEFEFEF首字节非0x7F/0xFF时,长度 = 首字节低 7 位 × 4;否则后 3 字节小端 × 4
中间格式(intermediate)0xEEEEEEEE前 4 字节小端(最高位掩掉)即负载长度
填充中间格式(padded)0xDDDDDDDD同中间格式,消息会补齐到 16 字节边界

判断逻辑见proto_tag_to_type(src/crypto.rs#L62-L72);三种格式的长度解析分别在next_abridged_len_at(src/crypto.rs#L167-L191)与next_intermediate_len_at(src/crypto.rs#L193-L207)。

几个关键设计细节:

  • 粘包/半包缓冲:数据先进缓冲区,攒够一条完整消息才吐出;读不到完整长度头就等待后续数据(src/crypto.rs#L100-L142);
  • 性能优化:用偏移量遍历缓冲区而非反复"删头",避免大量小包时的 O(N²) 拷贝;
  • 优雅降级:如果解析出长度为 0 的异常消息,disabled置位后改为原样透传(src/crypto.rs#L124-L128);
  • 收尾冲刷:连接结束时flush()把缓冲区残余一次性发完(src/crypto.rs#L144-L152)。

拆分结果直接决定 WebSocket 帧的边界——每条 MTProto 消息对应一个 WS 帧发送,这样上游kws{dc}.web.telegram.org服务才能按消息处理(src/proxy.rs#L901-L914)。

进阶:FakeTLS 伪装与 Secret Key 的 ee 模式

除了基础 MTProto 通道,tg-ws-proxy-android 还支持FakeTLS:客户端伪装成普通 TLS 连接(ee<secret><domain_hex>密钥形式),流量首字节就是标准 TLS 握手标记,在封包检测下更像日常浏览行为。代理端根据首字节判断走 FakeTLS 握手还是普通 MTProto 握手(src/proxy.rs#L1586-L1624)。这个能力在"部分绕过加载问题"的场景中非常有用,也是它作为 MTProto 加密代理与普通隧道工具的分水岭。

新手上手:三步让加密代理跑起来

  1. 安装并启动:打开应用 → 点"Запустить прокси"(启动代理),通知栏出现前台服务即代表本地 MTProto 代理(端口 1443)已就绪;
  2. 应用到 Telegram:点"Применить в Telegram",应用会通过tg://proxy把server / port / secret=dd<密钥>自动传给兼容客户端(AyuGram、Plus Messenger、NekoGram 等),在 Telegram 里确认即可;
  3. 观察连接:在日志页可以看到每次握手的 DC 编号、协议标识与上下行流量,验证 AES-256-CTR 转换链路是否健康。

涉及文件速查:

  • 应用主界面与"应用到 Telegram"入口:app/src/main/java/com/amurcanov/tgwsproxy/ui/ConnectionTab.kt
  • 前台代理服务:app/src/main/java/com/amurcanov/tgwsproxy/ProxyService.kt
  • Rust 原生库导出接口:src/lib.rs
  • 加密核心(AES-256-CTR + 拆分器):src/crypto.rs

写在最后

tg-ws-proxy-android 把"MTProto 加密、AES-256-CTR 密钥流、Secret Key 验证、消息拆分"这套服务端级机制完整搬到了手机本地:32 位 hex 的 Secret Key 是门禁,SHA-256(prekey + secret) 推导出四条 CTR 密钥流完成双向重加密,MsgSplitter 再按精简/中间/填充三种 MTProto 格式把字节流切成独立消息。理解了这三块,你不仅会用它,也能看懂任意 MTProto WebSocket 代理的实现原理 📱✨。

【免费下载链接】tg-ws-proxy-androidAndroid-форк популярного приложения Flowseal - tg-ws-proxy - локальный прокси-сервер MTProto с проксированием CF или без для частичного обхода проблем загрузки Telegram项目地址: https://gitcode.com/gh_mirrors/tg/tg-ws-proxy-android

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询