TG飞机安卓app客户端向服务器发送查询

2022-04-28 15:49   浏览:6028   Telegram

req_DH_params#d712e4be nonce:int128 server_nonce:int128 p:string q:string public_key_fingerprint:long encrypted_data:string = Server_DH_Params

       这里,encrypted_data的获取方式如下:TG安卓app下载

       new_nonce := 客户端生成的另一个(好的)随机数;在这个查询之后,客户端和服务器都知道它;

       数据 := 的序列化

       p_q_inner_data_dc#a9f55f95 pq:string p:string q:string nonce:int128 server_nonce:int128 new_nonce:int256 dc:int = P_Q_inner_data;

       p_q_inner_data_temp_dc#56fddf88 pq:string p:string q:string nonce:int128 server_nonce:int128 new_nonce:int256 dc:int expires_in:int = P_Q_inner_data;

encrypted_data := RSA_PAD (data, server_public_key),其中 RSA_PAD 是 RSA 的一个版本,带有 OAEP+ 填充的变体,在下面的 4.1 中解释)。

       有人可能会拦截查询并将其替换为他们自己的,独立地将 pq 分解为因子而不是客户端。唯一有意义的修改字段是 new_nonce,这将是入侵者必须重新生成的字段(因为入侵者无法解密客户端发送的加密数据)。由于所有后续消息都使用 new_nonce 加密或包含 new_nonce_hash,因此它们不会被客户端处理(入侵者无法使其看起来好像它们是由服务器生成的,因为它们不包含 new_nonce)。因此,这种拦截只会导致入侵者代替客户端完成授权密钥生成协议并创建新密钥(与客户端无关);然而,

       内部数据的另一种p_q_inner_data_temp_dc形式expires_in(服务器可以更早地丢弃其副本。在所有其他方面,临时密钥生成协议是相同的。创建临时密钥后,客户端通常通过auth.bindTempAuthKey方法将其绑定到其主体授权密钥,并将其用于所有客户端-服务器通信,直到过期;然后生成一个新的临时密钥。从而实现了客户端-服务器通信中的完美前向保密 (PFS)。阅读有关 PFS 的更多信息 »

       4.1) 上面提到的RSA_PAD(data, server_public_key) 实现如下:

       data_with_padding := 数据 + random_padding_bytes; -- 其中选择了random_padding_bytes,因此data_with_padding的结果长度正好是192字节,而data是要像以前一样加密的TL序列化数据。必须检查数据是否不超过 144 字节。

data_pad_reversed := BYTE_REVERSE(data_with_padding); -- 通过反转字节顺序从 data_with_padding 获得。TG安卓版下载

生成一个随机的 32 字节 temp_key。

data_with_hash := data_pad_reversed + SHA256(temp_key + data_with_padding); -- 在这个赋值之后,data_with_hash 正好是 224 字节长。

aes_encrypted := AES256_IGE(data_with_hash, temp_key, 0); -- AES256-IGE 加密,IV 为零。

temp_key_xor := temp_key XOR SHA256(aes_encrypted); -- 调整后的密钥,32 字节

key_aes_encrypted := temp_key_xor + aes_encrypted; -- 正好 256 字节(2048 位)长

key_aes_encrypted 的值与 server_pubkey 的 RSA 模数作为大端 2048 位(256 字节)无符号整数进行比较。如果 key_aes_encrypted 大于或等于 RSA 模数,则重复前面从生成新随机 temp_key 开始的步骤。否则执行最后一步:

       encrypted_data := RSA(key_aes_encrypted, server_pubkey); -- 256 字节大端整数从 RSA 公钥以 RSA 模数为模被提升到必要的幂,结果存储为由 256 个字节组成的大端整数(如果需要,前导零字节)。

服务器响应:

server_DH_params_ok#d0e8075c nonce:int128 server_nonce:int128 encrypted_answer:string = Server_DH_Params;

       如果查询不正确,服务器会返回-404错误并且必须重新握手(任何后续请求也会返回-404,即使它是正确的)。

这里,encrypted_answer 的获取方式如下:

new_once_hash := SHA1 (new_nonce) 的 128 个低位;

答案 := 序列化

  server_DH_inner_data#b5890dba nonce:int128 server_nonce:int128 g:int dh_prime:string g_a:string server_time:int = Server_DH_inner_data;

answer_with_hash := SHA1(answer) + answer + (0-15 随机字节); 使得长度可以被 16 整除;

tmp_aes_key := SHA1(new_nonce + server_nonce) + substr (SHA1(server_nonce + new_nonce), 0, 12);

tmp_aes_iv := substr (SHA1(server_nonce + new_nonce), 12, 8) + SHA1(new_nonce + new_nonce) + substr (new_nonce, 0, 4);

encrypted_answer := AES256_ige_encrypt (answer_with_hash, tmp_aes_key, tmp_aes_iv);        这里,tmp_aes_key 是一个 256 位的密钥,tmp_aes_iv 是一个 256 位的初始化向量。与使用 AES 加密的所有其他实例相同,加密数据在加密前立即用随机字节填充到可被 16 整除的长度。

       在这一步之后,new_nonce 仍然只有客户端和服务器知道。客户端确定响应的是服务器,并且响应是专门为响应客户端查询 req_DH_params 而生成的,因为响应数据是使用 new_nonce 加密的。

       客户端需要检查p = dh_prime是否是一个安全的 2048 位素数(意味着p和(p-1)/2都是素数,并且 2^2047 < p < 2^2048),并且g生成一个素数阶(p-1)/2的循环子群,即是二次余数mod p。由于g总是等于 2、3、4、5、6 或 7,这很容易使用二次互易定律完成,在p mod 4g上产生一个简单的条件——即p mod 8 = 7 for g = 2;p mod 3 = 2对于g = 3 ; g = 4没有额外条件;p mod 5 = 1 或 4对于g = 5 ; p mod 24 = 19 或 23对于g = 6;对于g = 7,p mod 7 = 3、5 或 6。在客户端检查g和p之后,缓存结果是有意义的,以免将来重复冗长的计算。

       如果验证时间过长(旧的移动设备就是这种情况),最初可能只运行 15 次 Miller-Rabin 迭代来验证p和(p - 1)/2的素数,错误概率不超过十亿分之一,并稍后在后台进行更多迭代。

       另一个优化是在客户端应用程序代码中嵌入一个小表,其中包含一些已知的“好”对 (g,p)(或者只是已知的安全素数p,因为g上的条件在执行期间很容易验证),在代码生成阶段检查,从而完全避免在运行时进行此类验证。服务器很少更改这些值,因此通常必须将服务器的dh_prime的当前值放入这样的表中。例如,dh_prime的当前值等于(以大端字节顺序)

       客户端计算随机的 2048 位数字b(使用足够量的熵)并向服务器发送消息

       set_client_DH_params#f5045f1f nonce:int128 server_nonce:int128 encrypted_data:string = Set_client_DH_params_answer;

       在这里,encrypted_data 是这样获得的:

g_b := pow(g, b) mod dh_prime;

数据 := 序列化

       client_DH_inner_data#6643b654 nonce:int128 server_nonce:int128 retry_id:long g_b:string = Client_DH_Inner_Data

data_with_hash := SHA1(data) + data + (0-15 随机字节); 使得长度可以被 16 整除;

encrypted_data := AES256_ige_encrypt (data_with_hash, tmp_aes_key, tmp_aes_iv);

       retry_id 字段在第一次尝试时等于 0;否则,它等于上一次失败尝试的 auth_key_aux_hash(参见条款 9)。

       此后, auth_key 等于pow(g, {ab}) mod dh_prime; 在服务器上,它被计算为pow(g_b, a) mod dh_prime,而在客户端上,它被计算为(g_a)^b mod dh_prime。

       auth_key_hash 计算为:= SHA1 (auth_key) 的 64 个低位。服务器检查是否已经有另一个具有相同 auth_key_hash 的密钥,并以下列方式之一进行响应。



温馨提示:请自行对该信息辨别真实和有效性,付款请找正规担保交易平台,以免造成损失!

声明:本站作为信息发布平台,拒绝任何违规、违法信息,发布的信息已经过审核处理。但无法对服务过程作出保证。

如有造成损失请保留证据并及时报警处理,本站不承担任何责任。对于虚假及欺骗信息请及时举报,本站第一时删除处理!