原文连接: Creating an Authorization Key
创建授权密钥
其实就是使用DH算法以及公私钥机制生成会话密钥的过程:
概述
1)客户端发送一个128位随机数nonce给服务,作为后续会话ID;
2)服务器应答一个128位随机数server_nonce,大素数积g*p,以及选择的公钥的索引;
元组(nonce,server_nonce)将在后续会话中作为标记使用;
3)客户端尝试分解pq;
- 客户端生成新的随机数new_nonce作为后续临时对称加密密钥使用;
编码后,将数据使用公钥加密发给服务器;
客户端生成新的随机数用于做返回数据的对称加密密钥使用,编码后,将数据使用公钥加密发给服务器;
5)服务器计算DH中 的秘钥a,并计算结果g_a发给客户端;
6)客户端使用new_nonce得到的密钥密码收到的数据;根据g_a,p, q 生成随机密钥b,使用DH算法计算出g_b;将g_b发送给服务器,并带上密钥的哈希的低比特(不能发完整哈希,不安全)用于校验;
7)双方都可以计算出密钥了,服务端验证密钥;
8)开始新的正式的通信;
开始
RPC调用的方式是使用一个叫做“Query”方式调用的,数据序列化的定义由 Binary Data Serialization 和 TL Language来描述。
大的数字都是使用大端优先的方式序列化为一个字符串。哈希函数,比如 SHA1就会返回一个20字节的字符串,这个也被理解为大端优先的一个大整数。
小数字(4B, 8B, 16B,32B) (int, long, int128, int256) 使用小端优先序列化;然而如果他们是SHA1的一部分则不会重新按大头重排,比如有个long(int64)的变量X用来表示SHA1的低64比特,那么这字符串中的最后8字节就可以直接取出来,翻译为64比特的整数。至于string和vector的序列化,在其他的帖子中讨论。
我们再发送消息前,需要使用密钥交换算法来获取授权密钥,如下:
一、 DH 执行前准备工作
1. 客户发送一个请求到服务器
req_pq_multi#be7e8ef1 nonce:int128 = ResPQ;
备注:这里使用了TL语言描述调用以及返回的数据,意思是要求调用签名为be7e8ef1的函数:
ResPQ req_pq_multi(int128 nonce);
客户端随机生成一个128比特随机数,定义为nonce,后续过程中将用于标识此客户端,或者可以理解为会话的session_id。
2. 服务端计算后发回应答
resPQ#05162463 nonce:int128 server_nonce:int128 pq:string server_public_key_fingerprints:Vector long = ResPQ;
这里叫做类型定义,用于数据的序列化,可以理解为返回这样一个结构体的序列化:
struct ResPQ
{
int128 nonce; // 标记会话
int128 server_nonce; // 标记会话
string pq; // 大素数积
Vector<long> server_public_key_fingerprints; // 公钥索引数组
}
在这里,字符串pq是一个自然数(二进制大端格式)。这个数是两个不同的奇数质数(p*q)的乘积;通常,pq小于或等于2^63-1;
服务器随机选择server_nonce的值;
server_public_key_fingerprints 是一组公钥指纹(RSA key fingerprints),也就是 服务器公钥的SHA1的低64比特;
公钥被定义为:
rsa_public_key n:string e:string = RSAPublicKey
理解为:
struct RSAPublicKey
{
string n; // 按照大端序列化为字符串
string e; // 按照大端序列化为字符串
}
所有后续消息都包含明文形式的一对值(nonce,server_nonce),以及加密部分,从而可以识别“临时会话”,即本页中描述的密钥生成协

本文详细介绍了使用DH算法及公私钥机制生成会话密钥的过程,包括客户端和服务端交互的具体步骤,如生成随机数nonce、执行密钥交换、计算及验证加密密钥auth_key等。
最低0.47元/天 解锁文章
1810

被折叠的 条评论
为什么被折叠?



