本文介绍了如何使用 Telegram API 实现授权?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 PHP 实现多重授权以与 Telegram REST API 交互.

我要解决什么任务?嗯,这很简单:我的网站上有几十个用户(他们都有像这里这样的 Carma(+10、-2、+1000 等)以及相关的组分类:网站管理员和客户).当他们达到一定数量的 carma 并且因为他们在他们的个人资料中获得授权后,他们会加入基于为他们自动生成的 Telegram 的私人聊天.

经过一番研究,我发现它非常复杂,因为:

  1. 我从未体验过为硬件绑定社交网络实现 API.
  2. 我查看了

    https://core.telegram.org/mtproto/samples-auth_key

    这种方法将使您更好地理解和介绍整个 Telegram API 中使用的原语,并可能帮助您开始组织您自己的一组函数和例程来处理您在接下来的步骤中需要的 - 实现其他功能的 API,因为生成 AuthKey 只是开始.

    第一步

    所有通信均通过 TCP - 一旦您获得了唯一的 api_id (https://core.telegram.org/api/obtaining_api_id#obtaining-api-id) 您会发现以下 IP 广告用于测试:149.154.167.40:433 api_id 是此时不需要生成 AuthKey

    设置发送/接收 TCP 处理循环的首选方法

    我拥有的是一个私有的 SendData,它只是将一个字节发送到连接到上面给定 IP 地址的实时套接字

    Private Sub SendData(b() As Byte, Optional read As Boolean = False)如果不是 IsConnected() 那么日志(连接关闭!",ConsoleColor.DarkRed)RaiseEvent Disconneted()退出子万一b = TCPPack(b)Dim arg = 带有 {.RemoteEndPoint = ep} 的新 SocketAsyncEventArgsAddHandler arg.Completed, AddressOf IO_Handlerarg.SetBuffer(b, 0, b.Length)尝试如果不是 soc.SendAsync(arg) 然后IO_Handler(soc, arg)万一如果阅读 那么读取数据()万一Catch ex 作为例外Log("SendData:" & ex.ToString, ConsoleColor.Red)结束尝试结束子私有子读取数据(可选等待整数 = 0)如果不是 IsConnected() 那么日志(连接关闭!",ConsoleColor.DarkRed)RaiseEvent Disconneted()退出子万一Dim arg = 带有 {.RemoteEndPoint = ep} 的新 SocketAsyncEventArgsAddHandler arg.Completed, AddressOf IO_HandlerDim b(BUFFER_SIZE - 1) 作为字节arg.SetBuffer(b, 0, BUFFER_SIZE)尝试如果不是 soc.ReceiveAsync(arg) 那么IO_Handler(soc, arg)万一Catch ex 作为例外Log("ReadMessages:" & ex.ToString, ConsoleColor.Red)结束尝试结束子Private Sub IO_Handler(sender As Object, e As SocketAsyncEventArgs)日志(${e.LastOperation}:{e.SocketError}:{e.BytesTransferred}",ConsoleColor.Cyan)选择案例 e.SocketError案例 SocketError.Success选择案例 e.LastOperationCase SocketAsyncOperation.Connect '一个套接字连接操作.日志(连接到"& e.ConnectSocket.RemoteEndPoint.ToString,ConsoleColor.Green)是.Set()案例 SocketAsyncOperation.Disconnect, SocketAsyncOperation.ConnectRaiseEvent Disconneted()Case SocketAsyncOperation.Receive '一个套接字接收操作.处理数据(e)结束选择案例 SocketError.ConnectionAbortedRaiseEvent Disconneted()结束选择结束子Private Sub HandleData(e As SocketAsyncEventArgs)如果 e.BytesTransferred = 0 然后 -- 没有未决数据Log(远端已关闭连接.")退出子万一Dim len As Integer = e.Buffer(0)昏暗的开始 = 1如果 len = &H7F 那么len = e.Buffer(1)len += e.Buffer(2) <<8len += e.Buffer(3) <<16开始 = 4万一长度 = 4 * 长度Dim data(len - 1) As ByteArray.Copy(e.Buffer, start, data, 0, len)进程响应(数据)读取数据()结束子

    最后,我们需要一个 TcpPack() 方法来帮助我们以 Telegram 期望的格式填充数据 - 请参阅下面的代码和注释

    私有函数 TCPPack(b As Byte()) As Byte()Dim a = 新列表(字节)Dim len = CByte(b.Length/4)如果 efSent = False 那么 --TCP 删节版efSent = 真a.Add(&HEF)万一如果 len >= &H7F 那么a.添加(&H7F)a.AddRange(BitConverter.GetBytes(len))别的a.添加(len)万一a.AddRange(b)——只有数据,没有序列号,没有CRC32返回一个.ToArray结束函数

    第 2 步

    通过基本的 TCP 发送/接收例程设置,我们可以开始准备要发送到电报的数据包,并拥有处理收到的特定响应的子例程 - ProcessResponse(data)

    接下来我们需要了解的是 Telegram 处理两大类消息 -

    未加密 - https://core.telegram.org/mtproto/description#unencrypted-message

    这些是带有 auth_key_id =0 的纯文本消息,生成的 AuthKey 始终使用这种类型的消息

    加密 - https://core.telegram.org/mtproto/description#encrypted-message-encrypted-data

    与 Telegram 服务器的所有进一步通信都将通过加密消息进行

    我选择有两个类来封装这两种消息类型.然后我可以有两个 Send(m) 方法来处理每种类型

    私有子发送(m As UnencryptedMessage)日志(m.ToString, ConsoleColor.DarkYellow, logTime:=False)发送数据(m.data,真)结束子私有子发送(m As EncryptedMessage)日志(m.ToString, ConsoleColor.DarkYellow, logTime:=False)发送数据(m.data,真)结束子

    目前只需要UnencryptedMessage

    公共类 UnencryptedMessage公共属性 auth_key_id 作为 Int64公共属性 message_id As Int64公共属性 data_length As Int32公共属性 message_data As Byte()公共属性 message_type As String公共属性数据 As Byte() = {}Sub New(auth_key As Int64, message_id As Int64, data As Byte())_auth_key_id = auth_key_message_id = message_id_data_length = 数据.长度_message_data = 数据message_type = B2Hr(data, 0, 4)Dim a = 新列表(字节)a.AddRange(BitConverter.GetBytes(auth_key_id)) --{0, 0, 0, 0, 0, 0, 0, 0}a.AddRange(BitConverter.GetBytes(message_id))a.AddRange(BitConverter.GetBytes(data_length))a.AddRange(message_data)Me.data = a.ToArray结束子Sub New(b As Byte())数据 = b昏暗跳过 = 0_auth_key_id = BitConverter.ToInt64(b, 跳过) : 跳过 += 8_message_id = BitConverter.ToInt64(b, 跳过) : 跳过 += 8_data_length = BitConverter.ToInt32(b, skip) : 跳过 += 4ReDim _message_data(_data_length - 1)Array.Copy(b, 跳过, _message_data, 0, b.Length - 跳过)message_type = B2Hr(_message_data, 0, 4)结束子公共覆盖函数 ToString() 作为字符串返回 $"原始数据:{B2H(数据)}auth_key_id: {i2H(auth_key_id)} {auth_key_id}message_id: {i2H(message_id)} {message_id}数据长度:{i2H(data_length)} {data_length}消息数据:{B2H(消息数据)}消息类型:{消息类型}"结束函数结束类

    第 3 步

    现在我们按照 https://core.telegram.org/mtproto/中概述的一系列步骤进行操作auth_key

    1. 客户端向服务器发送查询

    req_pq#60469778 nonce:int128 = ResPQ 选择nonce的值由客户端随机(随机数)并标识客户端在这次交流中.走完这一步,大家就都知道了.

    1. 服务器发送表单响应

    resPQ#05162463 nonce:int128 server_nonce:int128 pq:stringserver_public_key_fingerprints:向量长 = ResPQ

    我的方法很简单:

    Sub RequestPQAuthorization()发送(MTProto.req_pq)结束子

    在一个名为 MTProto 的类中,我根据交换的每个步骤的需要实现了一组共享函数.每种方法都只是建立一个加密的数据结构,将在需要时按上述方式发送

    我们从:req_pq

    共享函数 req_pq(Optional nonce As Byte() = Nothing) As UnencryptedMessage--req_pq#60469778--nonce:int128如果 nonce 什么都没有,那么ReDim nonce(15)RND.NextBytes(nonce)万一Dim d = 新列表(字节)d.AddRange({120, 151, 70, 96}) --60469778d.AddRange(nonce)返回新的 UnencryptedMessage(0, CreateMessageId, d.ToArray)结束函数私有共享函数 CreateMessageId() As Int64返回 CLng((Date.UtcNow.Ticks - ZERO_TICK) * 429.4967296)结束函数

    Public Const ZERO_TICK = 621355968000000000 -- 即 1970-01-01T00:00:00Z(UTC 时间 1970 年 1 月 1 日凌晨 12:00)

    现在我们在步骤 1

    中的过程响应方法

    Private Sub ProcessResponse(data As Byte())尝试Dim r = 新的 UnencryptedMessage(data)日志(r.ToString, ConsoleColor.Yellow, logTime:=False)选择案例 r.message_type案例 resPQ.Classid请求DHKeyExchange(新resPQ(r.message_data))案例 server_DH_params_ok.ClassidRequestSetDH_params(New server_DH_params_ok(r.message_data), new_nonce)案例 server_DH_params_fail.Classid日志(新 server_DH_params_fail(r.message_data).ToString,ConsoleColor.DarkMagenta)案例 dh_gen_ok.Classid日志(新 dh_gen_ok(r.message_data).ToString,ConsoleColor.Green)案例 dh_gen_retry.Classid日志(新 dh_gen_retry(r.message_data).ToString,ConsoleColor.DarkMagenta)案例 dh_gen_fail.Classid日志(新 dh_gen_fail(r.message_data).ToString,ConsoleColor.DarkMagenta)其他情况日志($未处理的类型:{r.message_type}",ConsoleColor.Magenta)结束选择Catch ex 作为例外日志($错误:{ex.ToString}",ConsoleColor.Red)Log(B2H(data), ConsoleColor.DarkRed, logTime:=False)结束尝试结束子

    到目前为止很好,收到的每个响应都有一个 message_type 代码.

    我们可以打开它并确定如何处理每个.我们需要立即处理 resPQ.

    我所做的是创建一组类,每个类处理特定的响应类型

    ''' ''' resPQ#05162463''' nonce:int128 server_nonce:int128 pq:string server_public_key_fingerprints:vector long = ResPQ''' </summary>Public NotInheritable Class resPQ : 继承 TLObject公共共享阴影只读属性 Classid As String = "05162463";公共属性 nonce As Byte()公共属性 server_nonce As Byte()公共属性 pq As Byte()公共属性指纹列表(UInt64)公共属性计数为 Int32Sub New(data As Byte())昏暗跳过 = 4nonce = Slice(data, skip, 16) : skip += 16server_nonce = 切片(数据,跳过,16):跳过 += 16跳过 += 1 'pq:string 的长度pq = 切片(数据,跳过,8):跳过 += 8跳过 += 3 '填充以完成 4 个字节跳过 += 4 '%(向量长) 1cb5c415计数 = i32r(数据,跳过):跳过 += 4指纹=新列表(UInt64)对于 i = 0 计数 - 1指纹.添加(u64r(数据,跳过))下一个结束子公共覆盖函数 ToString() 作为字符串返回 $"classid:{NameOf(resPQ)}#{Classid}随机数:{B2H(随机数)}server_nonce: {B2H(server_nonce)}pq: {B2H(pq)} {u64(pq)}计数:{i2H(count)} {count}指纹:{i2H(fingerprints(0))} {fingerprints(0)}"结束函数结束类

    每个都基于这个简单的对象

    公共 MustInherit 类 TLObject公共共享属性 ClassId 作为字符串公共 MustOverride 将函数 ToString() 覆盖为字符串结束类

    在此基础上,我们解决了第 3 步和第 3 步4

    工作量证明 3) 客户将 pq 分解为质因数,使得 p

    这开始了一轮 Diffie-Hellman 密钥交换.

    提交工作证明;服务器认证 4) 客户端发送查询到服务器

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

    这是在我上面的 ProcessResponse 例程中的 RequestDHKeyExchange(New resPQ(r.message_data)) 发起的

    Sub RequestDHKeyExchange(r As resPQ)日志(r.ToString, ConsoleColor.Gray, logTime:=False)'分解主要辅因子Dim pp = 新 PrimeProduct(r.pq)日志(pp.ToString, ConsoleColor.Gray, logTime:=False)'encrypted_data 生成Dim pq = New P_Q_inner_data(r.pq, pp.p, pp.q, r.nonce, r.server_nonce)new_nonce = pq.new_nonce'P_Q_inner_data 的序列化产生一些字符串数据.其次是encrypted_data'data_with_hash := SHA1(data) + data + (任何随机字节);使得长度等于 255Dim data_with_hash = 新列表(字节)'SHA1(data) = xxx- 40 =20 字节使用 sha1 = 新的 SHA1ManagedDim b = pq.ToBytesdata_with_hash.AddRange(sha1.ComputeHash(b))data_with_hash.AddRange(b)结束使用如果 data_with_hash.Count 

    您可以使用自己的 Prime-Decomposition 实现来替换这一行 Dim pp = New PrimeProduct(r.pq)

    以下是我如何使用 PollardBrent(Pollard Rho Brent 整数因子分解)https 进行学习的示例://stackoverflow.com/a/31978350/44080

    好的,如果你能跟进到这一点,你对我如何逐步分解 AuthKey 实现有一个大致的了解.

    您应该能够完成剩余的步骤 5-9.我要打很多字...

    如果到目前为止这个答案对任何人有帮助,那么我会抽出时间组织并发布剩余部分.

    我相信您在此过程中积累的例程和知识应该为您提供从头开始理解和实现您自己的独立 Telegram API 代码所需的工具.

    已完成交互转储

    03:33:26.591 连接:成功:003:33:26.593 连接到 149.154.167.40:44303:33:26.598原始数据:000000000000000000DC799836FE075614000000789746604479257F6C01C039A3DEAD031BC2D6A4auth_key_id: 0000000000000000 0message_id: 5607FE369879DC00 6199202922538589184数据长度:00000014 20消息数据:789746604479257F6C01C039A3DEAD031BC2D6A4消息类型:6046977803:33:26.600 发送:成功:4203:33:26.735 接收:成功:8503:33:26.737raw_data:0000000000000000015CF64539FE075640000000632416054479257F6C01C039A3DEAD031BC2D6A44F9DB065B36308CF4D9965725DD7153D0818DDCAF407B7CDCD00000015C4B51C01000000216BE86C022BB4C3auth_key_id: 0000000000000000 0消息 ID:5607FE3945F65C01 6199202934039141377数据长度:00000040 64消息数据:632416054479257F6C01C039A3DEAD031BC2D6A44F9DB065B36308CF4D9965725DD7153D0818DDCAF407B7CDCD00000015C4020C80C80C80C80C80C80C80C80C80C80C80C80C80C80C80C80C80C80C80C80C80C80C80C8065C065B36308CF4D9965725DD7153消息类型:0516246303:33:26.743分类号:resPQ#05162463随机数:4479257F6C01C039A3DEAD031BC2D6A4server_nonce:4F9DB065B36308CF4D9965725DD7153Dpq:18DDCAF407B7CDCD 1791811376213642701计数:00000001 1指纹:C3B42B026CE86B21 1410194362262096566503:33:26.810PQ:18DDCAF407B7CDCD 1791811376213642701电话:45F57B87 1173715847问:5AFE490B 152661428303:33:26.930raw_data:000000000000000000403CEE36FE075640010000BEE412D74479257F6C01C039A3DEAD031BC2D6A44F9DB065B36308CF4D9965725DD7153D0445F57B87000000045AFE490B000000216BE86C022BB4C3FE0001002DD190DDD93DFFC9EAF14DFAD3018D101E9E3EEC6C3FF4C7C1A067B32FB19AA2FDDFD087094947E793FA9F1A10A36A0B2916609811CFF1F345EE8FD9CDFFBCA4555E33A0446AB4A534500F621D112FCF59CAD4961BC87375F6835460B2E1B3B4088CE79843F7445DC5D87E0ACB0C4A979F68240C06358C4D2F95F86C0535CA643FBE8AF730E70BCBB54191D4F110E50D3244882722605657E808382445FA070A67AED1B2835238C05A00EBE960106838A284BC03D7A01453BA5355F06952F686263DD5B22B66524ED47F843340E9B7FC75BD58B6CC376C0B8B89E7292EDCC08D6CD0F1F9BF8418C2A58BC82B1928B051B3A0C20FA0AB22BA822EFABA6E141508auth_key_id: 0000000000000000 0消息 ID:5607FE36EE3C4000 6199202923977392128数据长度:00000140 320message_data:BEE412D74479257F6C01C039A3DEAD031BC2D6A44F9DB065B36308CF4D9965725DD7153D0445F57B87000000045AFE490B000000216BE86C022BB4C3FE0001002DD190DDD93DFFC9EAF14DFAD3018D101E9E3EEC6C3FF4C7C1A067B32FB19AA2FDDFD087094947E793FA9F1A10A36A0B2916609811CFF1F345EE8FD9CDFFBCA4555E33A0446AB4A534500F621D112FCF59CAD4961BC87375F6835460B2E1B3B4088CE79843F7445DC5D87E0ACB0C4A979F68240C06358C4D2F95F86C0535CA643FBE8AF730E70BCBB54191D4F110E50D3244882722605657E808382445FA070A67AED1B2835238C05A00EBE960106838A284BC03D7A01453BA5355F06952F686263DD5B22B66524ED47F843340E9B7FC75BD58B6CC376C0B8B89E7292EDCC08D6CD0F1F9BF8418C2A58BC82B1928B051B3A0C20FA0AB22BA822EFABA6E141508消息类型:D712E4BE03:33:26.933 发送:成功:34103:33:27.217 接收:成功:65603:33:27.217raw_data:0000000000000000011C9A9F39FE0756780200005C07E8D04479257F6C01C039A3DEAD031BC2D6A44F9DB065B36308CF4D9965725DD7153DFE500200752C7BDBB6A58D68B76D2E20DCECF611B2837CA34F3688B242192C633FBBC1EC9348880DA6E6AFF42B256D8476A2C432B60E93218F5B84982B0F9800E6EF918AEC4B729AB1A67C82EF2C4D281352D1BEAEB6B9026CAA0CA8FB03F9257E2CA034471EE25CF6E214BB770E233566A67155BE8FB8F9DA0A76964CFD19E9C97D3E57AAA26E7A6C16B12F2B2BFD4C437857032F0A7198567B9CD3A54BD06CE61A1EBACD70D464185719BC8E0381C99E80A5783D389BE73E97166A328CEDB3AA4D722D453EB4CA893299E41DDC81C798BC76CAF070BFF144F6800D8FE5B3B6BCC9A1138E7ADA6DAF3F581AAB0137A6D40E640E76F6539B1450EA30A55E3F56C2C0A8DCC6F9F4D4F185D25AF37B46B9D9B8ED5CA257DD32EDE02FF95C6174C9D4BA1E30035723C7E2DED9EB0794AAA1913073E4EA2D5649C5C491B252AF88FF1D71EFB5E9FFCA921F0F27F72723DD5014359D08101278DF3F9A9A10DDE54B93A386C6844A6D15AF142DA956A3999458D10BBDE4E947BE949199F088B91175EC9EEE3C95AC47C96D802B0DC91AA6DB5B8A03E0985412DD23CD33FD961175CD271E02BF8A05A537E8FE21CDB40EBAAC0C8D4718DA4499D5B5EF935B848F92C25E9CAE76021758EDD1AA202A0D0DC357348B0474069002EB8F5F2760F2C5BEE38C7CEA07737C28864F647F2406BD55ABD58EEED97A4C8E659143441B1F8CB8DEFE457B46B5E76541CAB63FA1CD3626F0A45DB8A37964BF2613A6C64E6E6E478D44A2AF19CAD6C2686FD55EC85CACD645E58C364CBBD09EF1C7FE7420A8EF277982B87CA18D16B97980B14D24747D9BC86563DA81DAauth_key_id: 0000000000000000 0消息 ID:5607FE399F9A1C01 6199202935543045121数据长度:00000278 632message_data:5C07E8D04479257F6C01C039A3DEAD031BC2D6A44F9DB065B36308CF4D9965725DD7153DFE500200752C7BDBB6A58D68B76D2E20DCECF611B2837CA34F3688B242192C633FBBC1EC9348880DA6E6AFF42B256D8476A2C432B60E93218F5B84982B0F9800E6EF918AEC4B729AB1A67C82EF2C4D281352D1BEAEB6B9026CAA0CA8FB03F9257E2CA034471EE25CF6E214BB770E233566A67155BE8FB8F9DA0A76964CFD19E9C97D3E57AAA26E7A6C16B12F2B2BFD4C437857032F0A7198567B9CD3A54BD06CE61A1EBACD70D464185719BC8E0381C99E80A5783D389BE73E97166A328CEDB3AA4D722D453EB4CA893299E41DDC81C798BC76CAF070BFF144F6800D8FE5B3B6BCC9A1138E7ADA6DAF3F581AAB0137A6D40E640E76F6539B1450EA30A55E3F56C2C0A8DCC6F9F4D4F185D25AF37B46B9D9B8ED5CA257DD32EDE02FF95C6174C9D4BA1E30035723C7E2DED9EB0794AAA1913073E4EA2D5649C5C491B252AF88FF1D71EFB5E9FFCA921F0F27F72723DD5014359D08101278DF3F9A9A10DDE54B93A386C6844A6D15AF142DA956A3999458D10BBDE4E947BE949199F088B91175EC9EEE3C95AC47C96D802B0DC91AA6DB5B8A03E0985412DD23CD33FD961175CD271E02BF8A05A537E8FE21CDB40EBAAC0C8D4718DA4499D5B5EF935B848F92C25E9CAE76021758EDD1AA202A0D0DC357348B0474069002EB8F5F2760F2C5BEE38C7CEA07737C28864F647F2406BD55ABD58EEED97A4C8E659143441B1F8CB8DEFE457B46B5E76541CAB63FA1CD3626F0A45DB8A37964BF2613A6C64E6E6E478D44A2AF19CAD6C2686FD55EC85CACD645E58C364CBBD09EF1C7FE7420A8EF277982B87CA18D16B97980B14D24747D9BC86563DA81DA消息类型:D0E8075C03:33:27.240classid: server_DH_params_ok#D0E8075C随机数:4479257F6C01C039A3DEAD031BC2D6A4server_nonce:4F9DB065B36308CF4D9965725DD7153Denc_answer:752C7BDBB6A58D68B76D2E20DCECF611B2837CA34F3688B242192C633FBBC1EC9348880DA6E6AFF42B256D8476A2C432B60E93218F5B84982B0F9800E6EF918AEC4B729AB1A67C82EF2C4D281352D1BEAEB6B9026CAA0CA8FB03F9257E2CA034471EE25CF6E214BB770E233566A67155BE8FB8F9DA0A76964CFD19E9C97D3E57AAA26E7A6C16B12F2B2BFD4C437857032F0A7198567B9CD3A54BD06CE61A1EBACD70D464185719BC8E0381C99E80A5783D389BE73E97166A328CEDB3AA4D722D453EB4CA893299E41DDC81C798BC76CAF070BFF144F6800D8FE5B3B6BCC9A1138E7ADA6DAF3F581AAB0137A6D40E640E76F6539B1450EA30A55E3F56C2C0A8DCC6F9F4D4F185D25AF37B46B9D9B8ED5CA257DD32EDE02FF95C6174C9D4BA1E30035723C7E2DED9EB0794AAA1913073E4EA2D5649C5C491B252AF88FF1D71EFB5E9FFCA921F0F27F72723DD5014359D08101278DF3F9A9A10DDE54B93A386C6844A6D15AF142DA956A3999458D10BBDE4E947BE949199F088B91175EC9EEE3C95AC47C96D802B0DC91AA6DB5B8A03E0985412DD23CD33FD961175CD271E02BF8A05A537E8FE21CDB40EBAAC0C8D4718DA4499D5B5EF935B848F92C25E9CAE76021758EDD1AA202A0D0DC357348B0474069002EB8F5F2760F2C5BEE38C7CEA07737C28864F647F2406BD55ABD58EEED97A4C8E659143441B1F8CB8DEFE457B46B5E76541CAB63FA1CD3626F0A45DB8A37964BF2613A6C64E6E6E478D44A2AF19CAD6C2686FD55EC85CACD645E58C364CBBD09EF1C7FE7420A8EF277982B87CA18D16B97980B14D24747D9BC86563DA81DAtmp_aes_key: 297CB750FF0052B67515B3F11B45F11F15D106BC25ED0027570D5B9D83102BFAtmp_aes_iv:CBDCF40A77B6A1C7CE74A1F8EC8E091A49FAD3B9A2499BFFFD084D537A53B36D答案:BA0D89B54479257F6C01C039A3DEAD031BC2D6A44F9DB065B36308CF4D9965725DD7153D03000000FE000100C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5BFE000100C49E858CA0107FF9B51DC88236370866BE4A69DDC2193930769C11722D2884CE5017AF60712B6BAC17F79DBA8701A25AAA901FDCB483C56A246C1CA7705FAA87F0AFD68EAC8FC5EC88307298DAF7252DD6D8630BF819D65F9E4B5624B6A05149B35B8509A63C2F2D05417F38DD0A90727F5D12CC4D213B5974C732FB261F6AC01426F2B7269C17230442AA8C9AFCCD927463C4EC8465F841D969F0C47FC270D8EC23B1F5D861EB6A5602CF6F87A02A56A4094E06509503CACE935461086668AC32E8C69A90EB19C3232B20635DFADFC6E4EDC11FA34A3E2E2BBA28DDCEF422120077D3A171A6A5B65744113AF0D0A1FC566D315CEB3E40C8FEC6FEC6FEC8000000000000classid:Server_DH_inner_data#B5890DBA随机数:4479257F6C01C039A3DEAD031BC2D6A4server_nonce:4F9DB065B36308CF4D9965725DD7153D克:00000003 3dh_prime:C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5BG_A:C49E858CA0107FF9B51DC88236370866BE4A69DDC2193930769C11722D2884CE5017AF60712B6BAC17F79DBA8701A25AAA901FDCB483C56A246C1CA7705FAA87F0AFD68EAC8FC5EC88307298DAF7252DD6D8630BF819D65F9E4B5624B6A05149B35B8509A63C2F2D05417F38DD0A90727F5D12CC4D213B5974C732FB261F6AC01426F2B7269C17230442AA8C9AFCCD927463C4EC8465F841D969F0C47FC270D8EC23B1F5D861EB6A5602CF6F87A02A56A4094E06509503CACE935461086668AC32E8C69A90EB19C3232B20635DFADFC6E4EDC11FA34A3E2E2BBA28DDCEF422120077D3A171A6A5B65744113AF0D0A1FC566D31DBBDB43F5DE35A7CE5F0BB0ECD服务器时间:5607FE39 1443364409客户时间:5607FE37 1443364407填充:646CF781176C3EACDH_Prime 安全吗?= 真classid:Client_DH_Inner_Data#6643B654随机数:4479257F6C01C039A3DEAD031BC2D6A4server_nonce:4F9DB065B36308CF4D9965725DD7153Dretry_id: 0000000000000000 0G_B:923A21384FE0318D569B2F2BEA667D1A999050A0A1B5AFDA39F2B890DEE45F9ED08E319C8243CD1496269CCF956DFA6C98633BDC2E26B1675C15D7904417EC2A74C687E682ED14182178BC0BD189F6E020131C87FD42A24798FCCD2416348EE0AAF534B652175BAC33E89C82874A8C3E8562815DDA213610167B10153EFC1BD1A0CFBACFEA22E3E8D80917F262D2C67BF1327A245CF7FE0E299F7517EE6A2F65568630A6191FEB0C1254F260A6554ED2BEE19E94AAB693E58DD032C26B9CAFEB0482F12DE2573B6E6D2816AC37ADDF3B99525FDBAF94690926320CC67ABF35D3EA6EC6CC7211BAF11FBDD6897959F6F1E3D4335B89B3024C1B3C0066246B5DCD03:33:27.590 enc_data:0A974C499344B093ADF321597858B1A6179E2A6C21F5FF9EB5DE687CDB57F8059509482FF9846FBE99D9411C13A645B26F73960424A13337D87DA879864FCA9D0883B643CF8EB594446038E0B6C4FD606D0CB77F1E00CCA6291DD65733F6A60217C7F366AD88972F107C381FD375F49DB57A2AB96988EC916629CD6F58B53F65DF4909AA773CCA43CE43671CA313528190213CF28A3B29BE26865BE22EB0C41E89CBD698C96CBC1B7B7F1586FBD61B422693859843F7D32083E3AB23D607FC4B874DB849F430F74483969ABA4603B483C94BCEB38F8EC90EEB58B338B325A8E37B57813CEC7E795B1B5517D732227856955C53BA18F52E55C6BCD8F1419D43D46DF2C2560B74BA7AA961BB4BDD09ABBC95E4F57AC4B8C89A67C7C5453A3EFB635D3977E0C3F0067C1F4D255F1F87E74A8E7E4272DFDEB9B85ABBEFA4953B2E0ECAA15C3C77773155C4013955BAB0D85F03:33:27.810 AUTH_KEY:87A801A14AD6426E6AD56B638B315DF9F5B66F77333DC8C0FAADB77A1D51E71B68F5BB9B21DB275F2C4CA495E6440DDEACBDB199C52C327F7E2E9D78921E0D632CCA63DB6384FAF387E9D41717899EE5D54609C2F88573BBE8128FB5864CB62BC7F0ED250CBB57929AA5198FE568FC76FB846262A505B42D04BCB87C9EB24007CE9F9BDEB79391E7E9425F3A3D5028410E129C078EB8644EAB770F8705D8228CFAEAA4478A0D8E326971C7C2223074C4302C1F1DE5D08AC00CBEBEE41981B57A4248B517386DE68A51D01087F0E58D75A4C0FD2D031BC5BFC08651C4133494B572150EDD1C486153E8F51F99771DD57F55B3A5BBAE1874F25E69150C4E3C139703:33:27.813raw_data:0000000000000000009C48D037FE0756780100001F5F04F54479257F6C01C039A3DEAD031BC2D6A44F9DB065B36308CF4D9965725DD7153DFE5001000A974C499344B093ADF321597858B1A6179E2A6C21F5FF9EB5DE687CDB57F8059509482FF9846FBE99D9411C13A645B26F73960424A13337D87DA879864FCA9D0883B643CF8EB594446038E0B6C4FD606D0CB77F1E00CCA6291DD65733F6A60217C7F366AD88972F107C381FD375F49DB57A2AB96988EC916629CD6F58B53F65DF4909AA773CCA43CE43671CA313528190213CF28A3B29BE26865BE22EB0C41E89CBD698C96CBC1B7B7F1586FBD61B422693859843F7D32083E3AB23D607FC4B874DB849F430F74483969ABA4603B483C94BCEB38F8EC90EEB58B338B325A8E37B57813CEC7E795B1B5517D732227856955C53BA18F52E55C6BCD8F1419D43D46DF2C2560B74BA7AA961BB4BDD09ABBC95E4F57AC4B8C89A67C7C5453A3EFB635D3977E0C3F0067C1F4D255F1F87E74A8E7E4272DFDEB9B85ABBEFA4953B2E0ECAA15C3C77773155C4013955BAB0D85Fauth_key_id: 0000000000000000 0消息 ID:5607FE37D0489C00 6199202927769852928数据长度:00000178 376message_data: 1F5F04F54479257F6C01C039A3DEAD031BC2D6A44F9DB065B36308CF4D9965725DD7153DFE5001000A974C499344B093ADF321597858B1A6179E2A6C21F5FF9EB5DE687CDB57F8059509482FF9846FBE99D9411C13A645B26F73960424A13337D87DA879864FCA9D0883B643CF8EB594446038E0B6C4FD606D0CB77F1E00CCA6291DD65733F6A60217C7F366AD88972F107C381FD375F49DB57A2AB96988EC916629CD6F58B53F65DF4909AA773CCA43CE43671CA313528190213CF28A3B29BE26865BE22EB0C41E89CBD698C96CBC1B7B7F1586FBD61B422693859843F7D32083E3AB23D607FC4B874DB849F430F74483969ABA4603B483C94BCEB38F8EC90EEB58B338B325A8E37B57813CEC7E795B1B5517D732227856955C53BA18F52E55C6BCD8F1419D43D46DF2C2560B74BA7AA961BB4BDD09ABBC95E4F57AC4B8C89A67C7C5453A3EFB635D3977E0C3F0067C1F4D255F1F87E74A8E7E4272DFDEB9B85ABBEFA4953B2E0ECAA15C3C77773155C4013955BAB0D85Fmessage_type: F5045F1F03:33:27.823  Send:Success:39703:33:27.983  Receive:Success:7303:33:27.985

    ....

    Regards.

    I want to implement multiple authorization using PHP for interaction with Telegram REST API.

    What task am I trying to solve? Well, it's simple: several dozens of users (all of them have a carma like here (+10, -2, +1000 etc.) with relevant group taxonomy: web-masters and customers) have a user profile on my website. After they reach a certain amount of carma and since they are authorized in their profile they are joined to private chats based on Telegram generated for them automatically.

    After some research, I found that it's very complicated because:

    1. I've never had an experience of API implementation for hardware-binded social networks.
    2. I took a look at https://core.telegram.org/api/auth, but it's completely unobvious how to implement these functions (for example auth.sendCode), using PHP or any other language. If these commands should be sent as JSON to server, then it doesn't look like JSON:

        auth.sentCode#efed51d9 phone_registered:Bool phone_code_hash:string send_call_timeout:int is_password:Bool = auth.SentCode;
      

      What is it? In which language is it written?

      UPD: It's written in TL (Type Language): https://core.telegram.org/mtproto/TL

    3. I've explored the source code of several clients (Webogram, Telegram-cli (tg), tdesktop), and I found several implementations of https://core.telegram.org/mtproto

    Unfortunately, none of them support multiple authorization on their side, and after a little bit of research, I have no idea where to dig deeper to find out more information.

    Also, these implementations look bulky and compound (for example, https://github.com/vysheng/tg):

    There I see bunch of servers (./tg/tgl/tgl.h):

    #define TG_SERVER_1 "149.154.175.50"
    #define TG_SERVER_2 "149.154.167.51"
    #define TG_SERVER_3 "149.154.175.100"
    #define TG_SERVER_4 "149.154.167.91"
    #define TG_SERVER_5 "149.154.171.5"
    

    I found several possibly appropriate functions (./tg/tgl/queries.c):

    void empty_auth_file (void) {
      if (TLS->test_mode) {
        bl_do_dc_option (TLS, 1, "", 0, TG_SERVER_TEST_1, strlen (TG_SERVER_TEST_1), 443);
        bl_do_dc_option (TLS, 2, "", 0, TG_SERVER_TEST_2, strlen (TG_SERVER_TEST_2), 443);
        bl_do_dc_option (TLS, 3, "", 0, TG_SERVER_TEST_3, strlen (TG_SERVER_TEST_3), 443);
        bl_do_set_working_dc (TLS, TG_SERVER_TEST_DEFAULT);
      } else {
        bl_do_dc_option (TLS, 1, "", 0, TG_SERVER_1, strlen (TG_SERVER_1), 443);
        bl_do_dc_option (TLS, 2, "", 0, TG_SERVER_2, strlen (TG_SERVER_2), 443);
        bl_do_dc_option (TLS, 3, "", 0, TG_SERVER_3, strlen (TG_SERVER_3), 443);
        bl_do_dc_option (TLS, 4, "", 0, TG_SERVER_4, strlen (TG_SERVER_4), 443);
        bl_do_dc_option (TLS, 5, "", 0, TG_SERVER_5, strlen (TG_SERVER_5), 443);
        bl_do_set_working_dc (TLS, TG_SERVER_DEFAULT);
      }
    }
    
    void bl_do_dc_option (struct tgl_state *TLS, int id, const char *name, int l1, const char *ip, int l2, int port) {
      struct tgl_dc *DC = TLS->DC_list[id];
      if (DC && !strncmp (ip, DC->ip, l2)) { return; }
    
      clear_packet ();
      out_int (CODE_binlog_dc_option);
      out_int (id);
      out_cstring (name, l1);
      out_cstring (ip, l2);
      out_int (port);
    
      add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer));
    }
    

    etc.

    What files should I transfer to PHP for multiple user auth implementation?Could you please help me to know where to start from and how to make it easier than it currently is?

    Thank you in advance!

    解决方案

    So far I have been able to implement the telegram authorization completely, but not in your requested language - PHP, I used vb.Net. However, I believe the same logic should apply.

    Creating a Telegram Authorization Key

    Telegram API is no walk in the park. Studying existing src code could be quite daunting (IMHO). Hence my approach was to study the online API documentation and implement the sample-auth_key outlined in the links below.

    https://core.telegram.org/mtproto/auth_key

    https://core.telegram.org/mtproto/samples-auth_key

    What this approach will give you is a better understanding and introduction to the primitives used throughout Telegram API, and possibly help you start organizing your own set of functions and routines to handle which you will need for the next steps - implementing other features of the API, since generating an AuthKey is just the beginning.

    Step 1

    All Communication is via TCP - Once you have obtained a unique api_id (https://core.telegram.org/api/obtaining_api_id#obtaining-api-id) you will find the following IP advertised for use in testing: 149.154.167.40:433 The api_id is not required at this point for generating an AuthKey

    Setup your preferred method of Send/Receive TCP processing Loop

    what I have is a private SendData that simply sends a bytes to a live socket connected to the give IP address above

    Private Sub SendData(b() As Byte, Optional read As Boolean = False)
        If Not IsConnected() Then
            Log("Connection Closed!", ConsoleColor.DarkRed)
            RaiseEvent Disconneted()
            Exit Sub
        End If
        
        b = TCPPack(b)
        
        Dim arg = New SocketAsyncEventArgs With {.RemoteEndPoint = ep}
        AddHandler arg.Completed, AddressOf IO_Handler
        arg.SetBuffer(b, 0, b.Length)
        
        Try
            If Not soc.SendAsync(arg) Then
                IO_Handler(soc, arg)
            End If
        
            If read Then
                ReadData()
            End If
        Catch ex As Exception
                Log("SendData: " & ex.ToString, ConsoleColor.Red)
        End Try
    
    End Sub
    
    Private Sub ReadData(Optional wait As Integer = 0)
        If Not IsConnected() Then
            Log("Connection Closed!", ConsoleColor.DarkRed)
            RaiseEvent Disconneted()
            Exit Sub
        End If
    
        Dim arg = New SocketAsyncEventArgs With {.RemoteEndPoint = ep}
        AddHandler arg.Completed, AddressOf IO_Handler
    
        Dim b(BUFFER_SIZE - 1) As Byte
        arg.SetBuffer(b, 0, BUFFER_SIZE)
    
        Try
            If Not soc.ReceiveAsync(arg) Then
                IO_Handler(soc, arg)
            End If
        Catch ex As Exception
            Log("ReadMessages: " & ex.ToString, ConsoleColor.Red)
        End Try
    End Sub
    
    Private Sub IO_Handler(sender As Object, e As SocketAsyncEventArgs)
        Log($"{e.LastOperation}:{e.SocketError}:{e.BytesTransferred}", ConsoleColor.Cyan)
    
        Select Case e.SocketError
            Case SocketError.Success
                Select Case e.LastOperation
                    Case SocketAsyncOperation.Connect 'A socket Connect operation.
                        Log("Connected to " & e.ConnectSocket.RemoteEndPoint.ToString, ConsoleColor.Green)
                        are.Set()
    
                        Case SocketAsyncOperation.Disconnect, SocketAsyncOperation.Connect
                            RaiseEvent Disconneted()
    
                    Case SocketAsyncOperation.Receive 'A socket Receive operation.
                            HandleData(e)
                End Select
    
            Case SocketError.ConnectionAborted
                    RaiseEvent Disconneted()
        End Select
    End Sub
    
    Private Sub HandleData(e As SocketAsyncEventArgs)
        If e.BytesTransferred = 0 Then --no pending data
            Log("The remote end has closed the connection.")
            Exit Sub
        End If
    
        Dim len As Integer = e.Buffer(0)
        Dim start = 1
    
        If len = &H7F Then
            len = e.Buffer(1)
            len += e.Buffer(2) << 8
            len += e.Buffer(3) << 16
            start = 4
        End If
    
        len = 4 * len
    
        Dim data(len - 1) As Byte
        Array.Copy(e.Buffer, start, data, 0, len)
    
    
        ProcessResponse(data)
    
        ReadData()
    End Sub
    

    Finally for this step, we need a TcpPack() method which helps us pad our data in the format Telegram expects - see code below with comments

    Private Function TCPPack(b As Byte()) As Byte()
        Dim a = New List(Of Byte)
        Dim len = CByte(b.Length / 4)
    
        If efSent = False Then --TCP abridged version
            efSent = True
            a.Add(&HEF)
        End If
    
        If len >= &H7F Then
            a.Add(&H7F)
            a.AddRange(BitConverter.GetBytes(len))
        Else
            a.Add(len)
        End If
    
        a.AddRange(b) --only data, no sequence number, no CRC32
    
        Return a.ToArray
    End Function
    

    STEP 2

    With the basic TCP send/receive routines setup, we can start preparing data packets to send to telegram and have sub routines for handling the specific responses received - ProcessResponse(data)

    What we need to understand next is the fact that Telegram handles 2 broad categories of messages -

    Unencrypted - https://core.telegram.org/mtproto/description#unencrypted-message

    These are plain text messages with their auth_key_id =0 generating an AuthKey uses this type of message throughout

    Encrypted - https://core.telegram.org/mtproto/description#encrypted-message-encrypted-data

    All further communication with Telegram Servers will be via encrypted messages

    I choose to have two classes to encapsulate both message types. I can then have two Send(m) methods that handles each type

    Private Sub Send(m As UnencryptedMessage)
        Log(m.ToString, ConsoleColor.DarkYellow, logTime:=False)
        SendData(m.data, True)
    End Sub
    
    Private Sub Send(m As EncryptedMessage)
        Log(m.ToString, ConsoleColor.DarkYellow, logTime:=False)
        SendData(m.data, True)
    End Sub
    

    For now only UnencryptedMessage is required

    Public Class UnencryptedMessage
        Public Property auth_key_id As Int64
        Public Property message_id As Int64
        Public Property data_length As Int32
        Public Property message_data As Byte()
        Public Property message_type As String
        Public Property data As Byte() = {}
        
        Sub New(auth_key As Int64, message_id As Int64, data As Byte())
            _auth_key_id = auth_key
            _message_id = message_id
            _data_length = data.Length
            _message_data = data
            message_type = B2Hr(data, 0, 4)
        
            Dim a = New List(Of Byte)
        
            a.AddRange(BitConverter.GetBytes(auth_key_id)) --{0, 0, 0, 0, 0, 0, 0, 0}
            a.AddRange(BitConverter.GetBytes(message_id))
            a.AddRange(BitConverter.GetBytes(data_length))
            a.AddRange(message_data)
        
            Me.data = a.ToArray
        End Sub
        
        Sub New(b As Byte())
            data = b
        
            Dim skip = 0
        
            _auth_key_id = BitConverter.ToInt64(b, skip) : skip += 8
            _message_id = BitConverter.ToInt64(b, skip) : skip += 8
            _data_length = BitConverter.ToInt32(b, skip) : skip += 4
        
            ReDim _message_data(_data_length - 1)
        
            Array.Copy(b, skip, _message_data, 0, b.Length - skip)
        
            message_type = B2Hr(_message_data, 0, 4)
        End Sub
        
        Public Overrides Function ToString() As String
                Return $"
            raw_data: {B2H(data)}
         auth_key_id: {i2H(auth_key_id)}  {auth_key_id}
          message_id: {i2H(message_id)}  {message_id}
         data_length: {i2H(data_length)}  {data_length}
        message_data: {B2H(message_data)}
        message_type: {message_type}
        "
        End Function
    End Class
    

    STEP 3

    Now we follow he series of steps outlined in https://core.telegram.org/mtproto/auth_key

    My approach for this is very simple:

    Sub RequestPQAuthorization()
        Send(MTProto.req_pq)
    End Sub
    

    In a Class called MTProto I implement a set of shared functions as required by each step of the exchange. Each method is simply building up an Encrypted data structure which will be sent as above where required

    We start with: req_pq

    Shared Function req_pq(Optional nonce As Byte() = Nothing) As UnencryptedMessage
        --req_pq#60469778 
        --nonce:int128
        If nonce Is Nothing Then
            ReDim nonce(15)
            RND.NextBytes(nonce)
        End If
    
        Dim d = New List(Of Byte)
        d.AddRange({120, 151, 70, 96}) --60469778
        d.AddRange(nonce)
    
        Return New UnencryptedMessage(0, CreateMessageId, d.ToArray)
    End Function
    
    Private Shared Function CreateMessageId() As Int64
        Return CLng((Date.UtcNow.Ticks - ZERO_TICK) * 429.4967296)
    End Function
    

    Public Const ZERO_TICK = 621355968000000000 -- i.e. 1970-01-01T00:00:00Z (January 1, 1970, at 12:00 AM UTC)

    Now our process response method from Step 1

    Private Sub ProcessResponse(data As Byte())
        Try
            Dim r = New UnencryptedMessage(data)
            Log(r.ToString, ConsoleColor.Yellow, logTime:=False)
    
            Select Case r.message_type
                Case resPQ.Classid
                    RequestDHKeyExchange(New resPQ(r.message_data))
                Case server_DH_params_ok.Classid
                    RequestSetDH_params(New server_DH_params_ok(r.message_data), new_nonce)
                Case server_DH_params_fail.Classid
                    Log(New server_DH_params_fail(r.message_data).ToString, ConsoleColor.DarkMagenta)
                Case dh_gen_ok.Classid
                    Log(New dh_gen_ok(r.message_data).ToString, ConsoleColor.Green)
                Case dh_gen_retry.Classid
                    Log(New dh_gen_retry(r.message_data).ToString, ConsoleColor.DarkMagenta)
                Case dh_gen_fail.Classid
                    Log(New dh_gen_fail(r.message_data).ToString, ConsoleColor.DarkMagenta)
                Case Else
                    Log($"Unhandled type: {r.message_type}", ConsoleColor.Magenta)
            End Select
        Catch ex As Exception
            Log($"Error: {ex.ToString}", ConsoleColor.Red)
            Log(B2H(data), ConsoleColor.DarkRed, logTime:=False)
        End Try
    End Sub
    

    Great so far, each response received has a message_type code.

    we can switch on that and determine how each is handled. We need to process resPQ right now.

    What i have done is to create a a set of classes that each handles a specific response type

    ''' <summary>
    ''' resPQ#05162463 
    ''' nonce:int128 server_nonce:int128 pq:string server_public_key_fingerprints:Vector long = ResPQ
    ''' </summary>
    Public NotInheritable Class resPQ : Inherits TLObject
        Public Shared Shadows ReadOnly Property Classid As String = "05162463"
        Public Property nonce As Byte()
        Public Property server_nonce As Byte()
        Public Property pq As Byte()
        Public Property fingerprints As List(Of UInt64)
        Public Property count As Int32
    
        Sub New(data As Byte())
            Dim skip = 4
            nonce = Slice(data, skip, 16) : skip += 16
            server_nonce = Slice(data, skip, 16) : skip += 16
            skip += 1 'length of pq:string
            pq = Slice(data, skip, 8) : skip += 8
            skip += 3 'padding to complete the 4-bytes
            skip += 4 '%(Vector long) 1cb5c415
            count = i32r(data, skip) : skip += 4
    
            fingerprints = New List(Of UInt64)
    
            For i = 0 To count - 1
                fingerprints.Add(u64r(data, skip))
            Next
        End Sub
    
        Public Overrides Function ToString() As String
            Return $"
         classid: {NameOf(resPQ)}#{Classid}
           nonce: {B2H(nonce)}
    server_nonce: {B2H(server_nonce)}
              pq: {B2H(pq)}  {u64(pq)}
           count: {i2H(count)}  {count}
    fingerprints: {i2H(fingerprints(0))}  {fingerprints(0)}
    "
        End Function
    End Class
    

    Each is based on this simple object

    Public MustInherit Class TLObject
        Public Shared Property ClassId As String
        Public MustOverride Overrides Function ToString() As String
    End Class
    

    Building on this, we tackle steps 3 & 4

    This is initiated here RequestDHKeyExchange(New resPQ(r.message_data)) in my ProcessResponse routine above

    Sub RequestDHKeyExchange(r As resPQ)
        Log(r.ToString, ConsoleColor.Gray, logTime:=False)
    
        'decompose prime cofactors
        Dim pp = New PrimeProduct(r.pq)
        Log(pp.ToString, ConsoleColor.Gray, logTime:=False)
    
        'encrypted_data Generation
        Dim pq = New P_Q_inner_data(r.pq, pp.p, pp.q, r.nonce, r.server_nonce)
        new_nonce = pq.new_nonce
    
        'The serialization Of P_Q_inner_data produces some String data. This Is followed by encrypted_data
        'data_with_hash := SHA1(data) + data + (any random bytes); such that the length equal 255 
        Dim data_with_hash = New List(Of Byte)
    
        'SHA1(data) = xxx- 40 =20 bytes
        Using sha1 = New SHA1Managed
            Dim b = pq.ToBytes
            data_with_hash.AddRange(sha1.ComputeHash(b))
            data_with_hash.AddRange(b)
        End Using
    
        If data_with_hash.Count < 255 Then
            Dim pad(255 - data_with_hash.Count - 1) As Byte
            RND.NextBytes(pad)
            data_with_hash.AddRange(pad)
        End If
    
        'RSA(data_with_hash, server_public_key) = xxx - 512 = 256 bytes
        Dim key = i2H(r.fingerprints(0)) 'c3b42b026ce86b21
        Dim zb = Crypto.rsaEncrypt(data_with_hash.ToArray, key)
        Send(MTProto.req_DH_params(r.nonce, r.server_nonce, pp.p, pp.q, r.fingerprints(0), zb))
    End Sub
    

    You can use your own implementation of Prime-Decomposition to replace this line Dim pp = New PrimeProduct(r.pq)

    Here is an example of how I learnt do it using PollardBrent (Pollard Rho Brent Integer Factorization) https://stackoverflow.com/a/31978350/44080

    Okay if you can follow up to this point you have a general idea of how i'm decomposing the AuthKey implementation step by step.

    You should be able to run through the remaining steps 5-9. It's a lot for me to type...

    If this answer so far is of any help to anyone, then i'll take out time to organize and post the remaining part.

    I believe that the routines and knowledge you build up along the way should give you the tools you need to both understand and implement your own independent Telegram API code from scratch.

    Completed Interaction Dump

    03:33:26.591  Connect:Success:0
    03:33:26.593  Connected to 149.154.167.40:443
    03:33:26.598
        raw_data: 000000000000000000DC799836FE075614000000789746604479257F6C01C039A3DEAD031BC2D6A4
     auth_key_id: 0000000000000000  0
      message_id: 5607FE369879DC00  6199202922538589184
     data_length: 00000014  20
    message_data: 789746604479257F6C01C039A3DEAD031BC2D6A4
    message_type: 60469778
    
    03:33:26.600  Send:Success:42
    03:33:26.735  Receive:Success:85
    03:33:26.737
        raw_data: 0000000000000000015CF64539FE075640000000632416054479257F6C01C039A3DEAD031BC2D6A44F9DB065B36308CF4D9965725DD7153D0818DDCAF407B7CDCD00000015C4B51C01000000216BE86C022BB4C3
     auth_key_id: 0000000000000000  0
      message_id: 5607FE3945F65C01  6199202934039141377
     data_length: 00000040  64
    message_data: 632416054479257F6C01C039A3DEAD031BC2D6A44F9DB065B36308CF4D9965725DD7153D0818DDCAF407B7CDCD00000015C4B51C01000000216BE86C022BB4C3
    message_type: 05162463
    
    03:33:26.743
         classid: resPQ#05162463
           nonce: 4479257F6C01C039A3DEAD031BC2D6A4
    server_nonce: 4F9DB065B36308CF4D9965725DD7153D
              pq: 18DDCAF407B7CDCD  1791811376213642701
           count: 00000001  1
    fingerprints: C3B42B026CE86B21  14101943622620965665
    
    03:33:26.810
    PQ: 18DDCAF407B7CDCD  1791811376213642701
     P: 45F57B87  1173715847
     Q: 5AFE490B  1526614283
    
    03:33:26.930
        raw_data: 000000000000000000403CEE36FE075640010000BEE412D74479257F6C01C039A3DEAD031BC2D6A44F9DB065B36308CF4D9965725DD7153D0445F57B87000000045AFE490B000000216BE86C022BB4C3FE0001002DD190DDD93DFFC9EAF14DFAD3018D101E9E3EEC6C3FF4C7C1A067B32FB19AA2FDDFD087094947E793FA9F1A10A36A0B2916609811CFF1F345EE8FD9CDFFBCA4555E33A0446AB4A534500F621D112FCF59CAD4961BC87375F6835460B2E1B3B4088CE79843F7445DC5D87E0ACB0C4A979F68240C06358C4D2F95F86C0535CA643FBE8AF730E70BCBB54191D4F110E50D3244882722605657E808382445FA070A67AED1B2835238C05A00EBE960106838A284BC03D7A01453BA5355F06952F686263DD5B22B66524ED47F843340E9B7FC75BD58B6CC376C0B8B89E7292EDCC08D6CD0F1F9BF8418C2A58BC82B1928B051B3A0C20FA0AB22BA822EFABA6E141508
     auth_key_id: 0000000000000000  0
      message_id: 5607FE36EE3C4000  6199202923977392128
     data_length: 00000140  320
    message_data: BEE412D74479257F6C01C039A3DEAD031BC2D6A44F9DB065B36308CF4D9965725DD7153D0445F57B87000000045AFE490B000000216BE86C022BB4C3FE0001002DD190DDD93DFFC9EAF14DFAD3018D101E9E3EEC6C3FF4C7C1A067B32FB19AA2FDDFD087094947E793FA9F1A10A36A0B2916609811CFF1F345EE8FD9CDFFBCA4555E33A0446AB4A534500F621D112FCF59CAD4961BC87375F6835460B2E1B3B4088CE79843F7445DC5D87E0ACB0C4A979F68240C06358C4D2F95F86C0535CA643FBE8AF730E70BCBB54191D4F110E50D3244882722605657E808382445FA070A67AED1B2835238C05A00EBE960106838A284BC03D7A01453BA5355F06952F686263DD5B22B66524ED47F843340E9B7FC75BD58B6CC376C0B8B89E7292EDCC08D6CD0F1F9BF8418C2A58BC82B1928B051B3A0C20FA0AB22BA822EFABA6E141508
    message_type: D712E4BE
    
    03:33:26.933  Send:Success:341
    03:33:27.217  Receive:Success:656
    03:33:27.217
        raw_data: 0000000000000000011C9A9F39FE0756780200005C07E8D04479257F6C01C039A3DEAD031BC2D6A44F9DB065B36308CF4D9965725DD7153DFE500200752C7BDBB6A58D68B76D2E20DCECF611B2837CA34F3688B242192C633FBBC1EC9348880DA6E6AFF42B256D8476A2C432B60E93218F5B84982B0F9800E6EF918AEC4B729AB1A67C82EF2C4D281352D1BEAEB6B9026CAA0CA8FB03F9257E2CA034471EE25CF6E214BB770E233566A67155BE8FB8F9DA0A76964CFD19E9C97D3E57AAA26E7A6C16B12F2B2BFD4C437857032F0A7198567B9CD3A54BD06CE61A1EBACD70D464185719BC8E0381C99E80A5783D389BE73E97166A328CEDB3AA4D722D453EB4CA893299E41DDC81C798BC76CAF070BFF144F6800D8FE5B3B6BCC9A1138E7ADA6DAF3F581AAB0137A6D40E640E76F6539B1450EA30A55E3F56C2C0A8DCC6F9F4D4F185D25AF37B46B9D9B8ED5CA257DD32EDE02FF95C6174C9D4BA1E30035723C7E2DED9EB0794AAA1913073E4EA2D5649C5C491B252AF88FF1D71EFB5E9FFCA921F0F27F72723DD5014359D08101278DF3F9A9A10DDE54B93A386C6844A6D15AF142DA956A3999458D10BBDE4E947BE949199F088B91175EC9EEE3C95AC47C96D802B0DC91AA6DB5B8A03E0985412DD23CD33FD961175CD271E02BF8A05A537E8FE21CDB40EBAAC0C8D4718DA4499D5B5EF935B848F92C25E9CAE76021758EDD1AA202A0D0DC357348B0474069002EB8F5F2760F2C5BEE38C7CEA07737C28864F647F2406BD55ABD58EEED97A4C8E659143441B1F8CB8DEFE457B46B5E76541CAB63FA1CD3626F0A45DB8A37964BF2613A6C64E6E6E478D44A2AF19CAD6C2686FD55EC85CACD645E58C364CBBD09EF1C7FE7420A8EF277982B87CA18D16B97980B14D24747D9BC86563DA81DA
     auth_key_id: 0000000000000000  0
      message_id: 5607FE399F9A1C01  6199202935543045121
     data_length: 00000278  632
    message_data: 5C07E8D04479257F6C01C039A3DEAD031BC2D6A44F9DB065B36308CF4D9965725DD7153DFE500200752C7BDBB6A58D68B76D2E20DCECF611B2837CA34F3688B242192C633FBBC1EC9348880DA6E6AFF42B256D8476A2C432B60E93218F5B84982B0F9800E6EF918AEC4B729AB1A67C82EF2C4D281352D1BEAEB6B9026CAA0CA8FB03F9257E2CA034471EE25CF6E214BB770E233566A67155BE8FB8F9DA0A76964CFD19E9C97D3E57AAA26E7A6C16B12F2B2BFD4C437857032F0A7198567B9CD3A54BD06CE61A1EBACD70D464185719BC8E0381C99E80A5783D389BE73E97166A328CEDB3AA4D722D453EB4CA893299E41DDC81C798BC76CAF070BFF144F6800D8FE5B3B6BCC9A1138E7ADA6DAF3F581AAB0137A6D40E640E76F6539B1450EA30A55E3F56C2C0A8DCC6F9F4D4F185D25AF37B46B9D9B8ED5CA257DD32EDE02FF95C6174C9D4BA1E30035723C7E2DED9EB0794AAA1913073E4EA2D5649C5C491B252AF88FF1D71EFB5E9FFCA921F0F27F72723DD5014359D08101278DF3F9A9A10DDE54B93A386C6844A6D15AF142DA956A3999458D10BBDE4E947BE949199F088B91175EC9EEE3C95AC47C96D802B0DC91AA6DB5B8A03E0985412DD23CD33FD961175CD271E02BF8A05A537E8FE21CDB40EBAAC0C8D4718DA4499D5B5EF935B848F92C25E9CAE76021758EDD1AA202A0D0DC357348B0474069002EB8F5F2760F2C5BEE38C7CEA07737C28864F647F2406BD55ABD58EEED97A4C8E659143441B1F8CB8DEFE457B46B5E76541CAB63FA1CD3626F0A45DB8A37964BF2613A6C64E6E6E478D44A2AF19CAD6C2686FD55EC85CACD645E58C364CBBD09EF1C7FE7420A8EF277982B87CA18D16B97980B14D24747D9BC86563DA81DA
    message_type: D0E8075C
    
    03:33:27.240
         classid: server_DH_params_ok#D0E8075C
           nonce: 4479257F6C01C039A3DEAD031BC2D6A4
    server_nonce: 4F9DB065B36308CF4D9965725DD7153D
      enc_answer: 752C7BDBB6A58D68B76D2E20DCECF611B2837CA34F3688B242192C633FBBC1EC9348880DA6E6AFF42B256D8476A2C432B60E93218F5B84982B0F9800E6EF918AEC4B729AB1A67C82EF2C4D281352D1BEAEB6B9026CAA0CA8FB03F9257E2CA034471EE25CF6E214BB770E233566A67155BE8FB8F9DA0A76964CFD19E9C97D3E57AAA26E7A6C16B12F2B2BFD4C437857032F0A7198567B9CD3A54BD06CE61A1EBACD70D464185719BC8E0381C99E80A5783D389BE73E97166A328CEDB3AA4D722D453EB4CA893299E41DDC81C798BC76CAF070BFF144F6800D8FE5B3B6BCC9A1138E7ADA6DAF3F581AAB0137A6D40E640E76F6539B1450EA30A55E3F56C2C0A8DCC6F9F4D4F185D25AF37B46B9D9B8ED5CA257DD32EDE02FF95C6174C9D4BA1E30035723C7E2DED9EB0794AAA1913073E4EA2D5649C5C491B252AF88FF1D71EFB5E9FFCA921F0F27F72723DD5014359D08101278DF3F9A9A10DDE54B93A386C6844A6D15AF142DA956A3999458D10BBDE4E947BE949199F088B91175EC9EEE3C95AC47C96D802B0DC91AA6DB5B8A03E0985412DD23CD33FD961175CD271E02BF8A05A537E8FE21CDB40EBAAC0C8D4718DA4499D5B5EF935B848F92C25E9CAE76021758EDD1AA202A0D0DC357348B0474069002EB8F5F2760F2C5BEE38C7CEA07737C28864F647F2406BD55ABD58EEED97A4C8E659143441B1F8CB8DEFE457B46B5E76541CAB63FA1CD3626F0A45DB8A37964BF2613A6C64E6E6E478D44A2AF19CAD6C2686FD55EC85CACD645E58C364CBBD09EF1C7FE7420A8EF277982B87CA18D16B97980B14D24747D9BC86563DA81DA
    
    tmp_aes_key: 297CB750FF0052B67515B3F11B45F11F15D106BC25ED0027570D5B9D83102BFA
     tmp_aes_iv: CBDCF40A77B6A1C7CE74A1F8EC8E091A49FAD3B9A2499BFFFD084D537A53B36D
         answer: BA0D89B54479257F6C01C039A3DEAD031BC2D6A44F9DB065B36308CF4D9965725DD7153D03000000FE000100C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5BFE000100C49E858CA0107FF9B51DC88236370866BE4A69DDC2193930769C11722D2884CE5017AF60712B6BAC17F79DBA8701A25AAA901FDCB483C56A246C1CA7705FAA87F0AFD68EAC8FC5EC88307298DAF7252DD6D8630BF819D65F9E4B5624B6A05149B35B8509A63C2F2D05417F38DD0A90727F5D12CC4D213B5974C732FB261F6AC01426F2B7269C17230442AA8C9AFCCD927463C4EC8465F841D969F0C47FC270D8EC23B1F5D861EB6A5602CF6F87A02A56A4094E06509503CACE935461086668AC32E8C69A90EB19C3232B20635DFADFC6E4EDC11FA34A3E2E2BBA28DDCEF422120077D3A171A6A5B65744113AF0D0A1FC566D31DBBDB43F5DE35A7CE5F0BB0ECD39FE0756646CF781176C3EAC
    
         classid: Server_DH_inner_data#B5890DBA
           nonce: 4479257F6C01C039A3DEAD031BC2D6A4
    server_nonce: 4F9DB065B36308CF4D9965725DD7153D
               g: 00000003  3
        dh_prime: C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5B
             g_a: C49E858CA0107FF9B51DC88236370866BE4A69DDC2193930769C11722D2884CE5017AF60712B6BAC17F79DBA8701A25AAA901FDCB483C56A246C1CA7705FAA87F0AFD68EAC8FC5EC88307298DAF7252DD6D8630BF819D65F9E4B5624B6A05149B35B8509A63C2F2D05417F38DD0A90727F5D12CC4D213B5974C732FB261F6AC01426F2B7269C17230442AA8C9AFCCD927463C4EC8465F841D969F0C47FC270D8EC23B1F5D861EB6A5602CF6F87A02A56A4094E06509503CACE935461086668AC32E8C69A90EB19C3232B20635DFADFC6E4EDC11FA34A3E2E2BBA28DDCEF422120077D3A171A6A5B65744113AF0D0A1FC566D31DBBDB43F5DE35A7CE5F0BB0ECD
     server_time: 5607FE39  1443364409
     client_time: 5607FE37  1443364407
         padding: 646CF781176C3EAC
    
    DH_Prime is Safe? = True
    
         classid: Client_DH_Inner_Data#6643B654
           nonce: 4479257F6C01C039A3DEAD031BC2D6A4
    server_nonce: 4F9DB065B36308CF4D9965725DD7153D
        retry_id: 0000000000000000  0
             g_b: 923A21384FE0318D569B2F2BEA667D1A999050A0A1B5AFDA39F2B890DEE45F9ED08E319C8243CD1496269CCF956DFA6C98633BDC2E26B1675C15D7904417EC2A74C687E682ED14182178BC0BD189F6E020131C87FD42A24798FCCD2416348EE0AAF534B652175BAC33E89C82874A8C3E8562815DDA213610167B10153EFC1BD1A0CFBACFEA22E3E8D80917F262D2C67BF1327A245CF7FE0E299F7517EE6A2F65568630A6191FEB0C1254F260A6554ED2BEE19E94AAB693E58DD032C26B9CAFEB0482F12DE2573B6E6D2816AC37ADDF3B99525FDBAF94690926320CC67ABF35D3EA6EC6CC7211BAF11FBDD6897959F6F1E3D4335B89B3024C1B3C0066246B5DCD
    
    03:33:27.590  enc_data: 0A974C499344B093ADF321597858B1A6179E2A6C21F5FF9EB5DE687CDB57F8059509482FF9846FBE99D9411C13A645B26F73960424A13337D87DA879864FCA9D0883B643CF8EB594446038E0B6C4FD606D0CB77F1E00CCA6291DD65733F6A60217C7F366AD88972F107C381FD375F49DB57A2AB96988EC916629CD6F58B53F65DF4909AA773CCA43CE43671CA313528190213CF28A3B29BE26865BE22EB0C41E89CBD698C96CBC1B7B7F1586FBD61B422693859843F7D32083E3AB23D607FC4B874DB849F430F74483969ABA4603B483C94BCEB38F8EC90EEB58B338B325A8E37B57813CEC7E795B1B5517D732227856955C53BA18F52E55C6BCD8F1419D43D46DF2C2560B74BA7AA961BB4BDD09ABBC95E4F57AC4B8C89A67C7C5453A3EFB635D3977E0C3F0067C1F4D255F1F87E74A8E7E4272DFDEB9B85ABBEFA4953B2E0ECAA15C3C77773155C4013955BAB0D85F
    03:33:27.810  auth_Key: 87A801A14AD6426E6AD56B638B315DF9F5B66F77333DC8C0FAADB77A1D51E71B68F5BB9B21DB275F2C4CA495E6440DDEACBDB199C52C327F7E2E9D78921E0D632CCA63DB6384FAF387E9D41717899EE5D54609C2F88573BBE8128FB5864CB62BC7F0ED250CBB57929AA5198FE568FC76FB846262A505B42D04BCB87C9EB24007CE9F9BDEB79391E7E9425F3A3D5028410E129C078EB8644EAB770F8705D8228CFAEAA4478A0D8E326971C7C2223074C4302C1F1DE5D08AC00CBEBEE41981B57A4248B517386DE68A51D01087F0E58D75A4C0FD2D031BC5BFC08651C4133494B572150EDD1C486153E8F51F99771DD57F55B3A5BBAE1874F25E69150C4E3C1397
    03:33:27.813
        raw_data: 0000000000000000009C48D037FE0756780100001F5F04F54479257F6C01C039A3DEAD031BC2D6A44F9DB065B36308CF4D9965725DD7153DFE5001000A974C499344B093ADF321597858B1A6179E2A6C21F5FF9EB5DE687CDB57F8059509482FF9846FBE99D9411C13A645B26F73960424A13337D87DA879864FCA9D0883B643CF8EB594446038E0B6C4FD606D0CB77F1E00CCA6291DD65733F6A60217C7F366AD88972F107C381FD375F49DB57A2AB96988EC916629CD6F58B53F65DF4909AA773CCA43CE43671CA313528190213CF28A3B29BE26865BE22EB0C41E89CBD698C96CBC1B7B7F1586FBD61B422693859843F7D32083E3AB23D607FC4B874DB849F430F74483969ABA4603B483C94BCEB38F8EC90EEB58B338B325A8E37B57813CEC7E795B1B5517D732227856955C53BA18F52E55C6BCD8F1419D43D46DF2C2560B74BA7AA961BB4BDD09ABBC95E4F57AC4B8C89A67C7C5453A3EFB635D3977E0C3F0067C1F4D255F1F87E74A8E7E4272DFDEB9B85ABBEFA4953B2E0ECAA15C3C77773155C4013955BAB0D85F
     auth_key_id: 0000000000000000  0
      message_id: 5607FE37D0489C00  6199202927769852928
     data_length: 00000178  376
    message_data: 1F5F04F54479257F6C01C039A3DEAD031BC2D6A44F9DB065B36308CF4D9965725DD7153DFE5001000A974C499344B093ADF321597858B1A6179E2A6C21F5FF9EB5DE687CDB57F8059509482FF9846FBE99D9411C13A645B26F73960424A13337D87DA879864FCA9D0883B643CF8EB594446038E0B6C4FD606D0CB77F1E00CCA6291DD65733F6A60217C7F366AD88972F107C381FD375F49DB57A2AB96988EC916629CD6F58B53F65DF4909AA773CCA43CE43671CA313528190213CF28A3B29BE26865BE22EB0C41E89CBD698C96CBC1B7B7F1586FBD61B422693859843F7D32083E3AB23D607FC4B874DB849F430F74483969ABA4603B483C94BCEB38F8EC90EEB58B338B325A8E37B57813CEC7E795B1B5517D732227856955C53BA18F52E55C6BCD8F1419D43D46DF2C2560B74BA7AA961BB4BDD09ABBC95E4F57AC4B8C89A67C7C5453A3EFB635D3977E0C3F0067C1F4D255F1F87E74A8E7E4272DFDEB9B85ABBEFA4953B2E0ECAA15C3C77773155C4013955BAB0D85F
    message_type: F5045F1F
    
    03:33:27.823  Send:Success:397
    03:33:27.983  Receive:Success:73
    03:33:27.985
    

    ....

    Regards.

    这篇关于如何使用 Telegram API 实现授权?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-14 18:21