Skip to content

Instantly share code, notes, and snippets.

@zii
Last active May 2, 2018 06:06
Show Gist options
  • Save zii/0b4ebda5c9c7993dcf40db734c5c93f1 to your computer and use it in GitHub Desktop.
Save zii/0b4ebda5c9c7993dcf40db734c5c93f1 to your computer and use it in GitHub Desktop.
客户端发包分三层:
第一层 = Protocal[4] + AESKeys[52] + 0xefefefef[4]
第二层 = Length[1/4] + AuthKeyID[8] + MsgKey[16]
第三层 = Salt[8] + SessionID[8] + MessageID[8] + SeqNo[4] + Length[4] + TLObject[:] + Padding[<28]
第一层加密使用AES256-CTR模式, 第二层加密使用AES256-IGE模式.
服务器发包(同客户端的第二三层):
第一层 = Length[1/4] + AuthKeyID[8] + MsgKey[16]
第二层 = Salt[8] + SessionID[8] + MessageID[8] + SeqNo[4] + Length[4] + TLObject[:] + Padding[<28]
服务端的包最终由上次接受的客户端请求包的AESKey部分再次加密, 然后发出.
名词解释:
SessionID是当前会话的编号.
Salt是周期性改变的一个数值, 用来保护重放攻击, 还有用来同步客户端时钟. (服务端生成的)
MessageID是当前会话的唯一消息编号, 并且用作时间戳.
SeqNo是请求应答用的序号, 应答seqno=请求seqno+1.
Padding是为了把长度补齐为16字节的倍数, 16字节即128位, 是AES的固定要求.
Pts是服务器推送通知的编号(自增)
生成AuthKey:
1. 客户端发送req_pq请求.
2. 服务端返回resPQ, 这里包含一个大数pq(两个质数的积), 和一个服务端RSA公钥footprint.
3. 客户端将pq因数分解为p和q, 这里仅仅是为了让客户端多点计算量, 用来做anti-DDos保护. 并非RSA算法的那个pq.
客户端发送req_DH_params, 除了p和q, 本次主要目的是将一个重要的参数new_nonce用RSA加密发送给服务端.
说白了telegram用RSA就做了这一件事, 为了发送一个new_nonce.
4. 接下来才是DH算法, 服务端用过RSA私钥解密出new_nonce, 生成(g, p, g^a), 发送server_DH_params_ok.
5. 客户端生成b, 算出auth_key=g^ab, 把g_b发给服务端, set_client_DH_params.
6. 服务端作出最终响应, dh_gen_ok.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment