← 返回列表

Telegram核心社群收录 深入理解MTProto 2.0的加密握手过程

分类:Telegram频道发布于:2026-09-16

telegram搜

当 Telegram 客户端第一次连接数据中心时,服务器还不知道它是谁,双方也没有可直接使用的共享密钥。MTProto 2.0 加密握手的任务,就是在不安全网络中协商出一把长期授权密钥,并确认整个交换过程没有被篡改。

这套流程经常被简单描述为“RSA 加密加上 Diffie-Hellman 交换”,但真正决定实现是否安全的,是随机数、素数校验、指纹匹配、临时 AES 密钥派生和摘要验证等细节。下面将按照真实协议顺序,拆解每一个关键步骤。

🔐 MTProto 2.0 握手究竟解决什么问题

MTProto 将传输层、加密层和 API 层分开设计,TCP、WebSocket 或 HTTP 只负责传输字节,并不直接提供 Telegram 账号级别的加密身份。客户端必须先完成授权密钥交换,才能发送后续的加密 API 请求。

握手最终生成的核心结果是一个通常为 2048 位的 auth_key。客户端还会根据它计算 64 位 auth_key_id,服务器借此快速定位对应密钥,而不需要在数据包里发送完整密钥。

auth_key = g^(ab) mod dh_prime
auth_key_id = lower_64_bits(SHA1(auth_key))

需要注意的是,auth_key_id 不是秘密,它只是密钥标识符。真正必须保密的是 auth_key,一旦它被窃取,攻击者可能伪造该授权会话。

1️⃣ 第一阶段:请求 PQ 与建立随机数上下文

客户端首先生成一个 128 位随机值 nonce,通过未加密消息发送 req_pq_multi。这个随机数会贯穿后续响应,用于将每条消息绑定到本次握手,防止旧数据被直接重放。

Client -> Server:
req_pq_multi {
  nonce: int128
}

Server -> Client:
resPQ {
  nonce: int128
  server_nonce: int128
  pq: bytes
  server_public_key_fingerprints: Vector<long>
}

服务器返回相同的 nonce、新生成的 server_nonce、合数 pq,以及一组可用 RSA 公钥指纹。客户端必须先确认响应中的 nonce 与请求完全一致,否则应立即中止握手。

随后客户端将 pq 分解为两个素数 p 与 q,并保证 p 小于 q。这里的 pq 通常被设计成客户端可以快速分解的规模,它并不是用来承担长期密码学安全性的 RSA 模数。

公钥指纹为什么重要?

Telegram 客户端预置官方数据中心的 RSA 公钥,并计算对应指纹。只有服务器返回的指纹与本地可信公钥匹配时,客户端才能继续,这一步构成了服务器身份认证的基础。

如果开发者从网络动态下载公钥却不验证可信来源,中间人就可能替换公钥并接管后续交换。实现第三方客户端时,必须使用官方公布且经过核验的密钥集合。

2️⃣ 第二阶段:使用 RSA 保护客户端参数

客户端再生成一个 256 位 new_nonce,并把 pq、p、q、nonce、server_nonce 及 new_nonce 组成内部对象。该对象经过协议规定的填充和哈希处理后,使用匹配指纹对应的服务器 RSA 公钥加密。

Client -> Server:
req_DH_params {
  nonce
  server_nonce
  p
  q
  public_key_fingerprint
  encrypted_data
}

encrypted_data 包含:
p_q_inner_data + new_nonce + 协议规定的摘要与填充

Telegram核心社群收录 RSA 在这里并不直接加密最终 auth_key,而是保护建立临时加密通道所需的客户端随机材料。服务器利用 RSA 私钥解开 encrypted_data 后,才能获得 new_nonce。

Telegram核心社群收录 从这一刻起,客户端和服务器都掌握了 new_nonce 与 server_nonce,可以独立派生出相同的临时 AES 密钥和初始化向量。它们仅用于保护当前握手中的 Diffie-Hellman 参数,不应被当成最终会话密钥。

tmp_aes_key =
  SHA1(new_nonce || server_nonce) ||
  first_12_bytes(SHA1(server_nonce || new_nonce))

tmp_aes_iv =
  last_8_bytes(SHA1(server_nonce || new_nonce)) ||
  SHA1(new_nonce || new_nonce) ||
  first_4_bytes(new_nonce)

电报精准找群黑科技提示:

由于 Telegram 官方搜索对中文支持极差,很多优质的推广、技术和资源群组隐藏极深。如果你正在寻找相关的活跃社群,强烈推荐使用本站首页的 【TTSO - Telegram 智能搜索 Bot】。作为目前最好用的电报综合搜索导航,只需输入关键词,即可秒级触达数十万个精选 TG 中文群组、资源频道。一键直达,帮你节省 90% 的找群时间!

3️⃣ 第三阶段:验证服务器 DH 参数

服务器返回 server_DH_params_ok,其中的 encrypted_answer 使用刚才派生的临时密钥,通过 AES-256-IGE 加密。客户端解密后,可以取得 DH 素数、生成元 g、服务器公开值 g_a、服务器时间以及前述随机数。

server_DH_inner_data {
  nonce
  server_nonce
  g
  dh_prime
  g_a
  server_time
}

此处不能只验证 AES 解密是否成功,客户端还必须核对内部摘要、nonce 与 server_nonce。任何一个字段不一致,都意味着数据损坏、实现错误或潜在攻击。

更关键的是,客户端必须验证 dh_prime、g 和 g_a 的合法性。包括确认 dh_prime 是安全素数、生成元符合约束,以及 g_a 没有落入过小或靠近模数边界的危险区间。

成熟客户端通常缓存已验证的标准 DH 素数,以减少重复的大整数素性测试。即便如此,也不能为了性能完全跳过校验,否则恶意参数可能把密钥空间压缩到可枚举范围。

4️⃣ 第四阶段:生成 auth_key 并确认握手

客户端生成高质量随机私有指数 b,计算公开值 g_b = g^b mod dh_prime,同时根据服务器的 g_a 计算共享授权密钥。私有指数必须来自密码学安全随机数生成器,不能使用时间戳或普通伪随机函数代替。

g_b = g^b mod dh_prime
auth_key = g_a^b mod dh_prime

Client -> Server:
set_client_DH_params {
  nonce
  server_nonce
  encrypted_data(client_DH_inner_data)
}

服务器使用自身私有指数 a 和客户端公开值 g_b 计算同一个结果,即 g_b^a mod dh_prime。基于 Diffie-Hellman 的数学性质,双方得到相同 auth_key,但网络监听者无法仅凭 g_a 与 g_b 高效推导它。

成功时服务器返回 dh_gen_ok,其中包含由 new_nonce 和 auth_key 派生的确认摘要。客户端必须计算并比较 new_nonce_hash1,不能把收到 dh_gen_ok 本身视为成功证明。

auth_key_aux_hash = first_8_bytes(SHA1(auth_key))

new_nonce_hash1 =
  lower_128_bits(
    SHA1(new_nonce || 0x01 || auth_key_aux_hash)
  )

协议还可能返回 dh_gen_retrydh_gen_fail,分别表示需要重新生成客户端 DH 值或握手失败。实现时应设置严格的重试上限,避免异常服务器诱导客户端无限计算。

🧩 MTProto 2.0 与后续消息加密的关系

Telegram核心社群收录 握手完成并不等于用户已经登录,它只表示客户端与特定 Telegram 数据中心建立了授权加密上下文。之后仍需通过 API 完成验证码、二维码或二次验证密码等账号认证流程。

后续加密消息会结合 auth_key、消息密钥 msg_key、方向标记和填充内容派生 AES 密钥与 IV。MTProto 2.0 相比旧版本强化了消息密钥派生,使密文与更多明文内容及授权密钥片段相关联。

普通 Telegram 云端聊天采用客户端到服务器的 MTProto 加密,并不是端到端加密。只有秘密聊天使用端到端方案,因此不能把“完成 MTProto 握手”误解为服务器无法读取普通云端消息。

Telegram核心社群收录 实现者必须检查的安全清单

随机数质量:nonce、new_nonce 和 DH 私有指数必须由操作系统提供的 CSPRNG 生成,并避免重复使用。

完整性验证:每次解密后都要核对协议摘要、构造器、长度和随机数,比较敏感摘要时宜采用恒定时间方法。

大整数校验:验证 pq 分解结果、DH 安全素数、生成元和公开值范围,同时拒绝非规范编码与超长输入。

密钥存储:auth_key 应保存在系统安全存储中,并限制日志、崩溃转储和备份程序访问,临时密钥使用后应尽快清理。

时间同步:利用 server_time 调整客户端与服务器的时间差,但不要直接修改系统时钟,避免消息标识符和会话状态异常。

Telegram核心社群收录 ❓ 常见问题解答(FAQ)

MTProto 2.0 握手是否依赖 HTTPS?

不依赖,MTProto 可以运行在多种传输之上,其授权密钥交换本身负责密码学保护。即使外层使用 HTTPS,也不能省略 RSA 指纹、DH 参数和摘要校验。

为什么先使用 RSA,再使用 Diffie-Hellman?

RSA 公钥用于认证服务器并安全传递 new_nonce,Diffie-Hellman 则负责协商双方共享的 auth_key。两者职责不同,组合后既能识别服务器,又无需直接传输最终密钥。

auth_key 会在每次启动 Telegram 时重新生成吗?

通常不会,长期授权密钥会安全保存在本地并重复用于对应数据中心。只有密钥丢失、被撤销、授权重置或客户端主动创建新密钥时,才需要重新执行完整握手。

握手失败最常见的原因是什么?

常见原因包括 RSA 公钥指纹过期、nonce 字节序处理错误、TL 序列化长度不正确、AES-IGE 实现错误,以及遗漏 DH 参数范围检查。调试时可以记录消息类型和长度,但绝不能输出 auth_key、私有指数或完整 new_nonce

可以自己从零实现 MTProto 握手吗?

可以,但不建议在生产环境中凭教程自行拼装密码学流程。优先采用经过审计的 Telegram 官方库或成熟实现,并以最新协议文档和测试向量进行交叉验证。

从整体上看,MTProto 2.0 握手是一条环环相扣的信任链:可信 RSA 公钥认证服务器,随机数绑定会话,临时 AES 通道保护 DH 参数,Diffie-Hellman 生成 auth_key,最终摘要确认双方结果一致。任何一步被省略,都可能让看似成功的连接失去应有的安全边界。

telegram中文搜索群组
Telegram搜索入口客服ID@TTSO联系