php - 如何使用 Telegram API 实现授权?

标签 php algorithm api rest telegram

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

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

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

  • 我从来没有为硬件绑定(bind)的社交网络实现 API 的经验。
  • 我看了https://core.telegram.org/api/auth ,但是如何使用PHP或任何其他语言来实现这些功能(例如auth.sendCode)完全不明显。如果这些命令应该作为 JSON 发送到服务器,那么它看起来不像 JSON:
      auth.sentCode#efed51d9 phone_registered:Bool phone_code_hash:string send_call_timeout:int is_password:Bool = auth.SentCode;
    

    它是什么?它是用哪种语言编写的?

    更新:它是用 TL(类型语言)编写的:https://core.telegram.org/mtproto/TL
  • 我探索了几个客户端(Webogram、Telegram-cli (tg)、tdesktop)的源代码,发现了https://core.telegram.org/mtproto的几个实现

  • 不幸的是,他们都没有支持多重授权,经过一些研究,我不知道去哪里深入挖掘以找到更多信息。

    此外,这些实现看起来庞大而复杂(例如, https://github.com/vysheng/tg ):
    enter image description here

    在那里我看到一堆服务器(./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"
    

    我发现了几个可能合适的函数(./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));
    }
    

    等等。

    我应该将哪些文件传输到 PHP 以实现多用户身份验证?
    你能帮我知道从哪里开始以及如何使它比现在更容易吗?

    先感谢您!

    最佳答案

    到目前为止,我已经能够完全实现电报授权,但不能使用您请求的语言 - PHP,我使用了 vb.Net。但是,我相信同样的逻辑应该适用。
    创建电报授权 key
    Telegram API 不是在公园里散步。研究现有的 src 代码可能非常令人生畏(恕我直言)。因此,我的方法是研究在线 API 文档并实现以下链接中概述的 sample-auth_key。
    https://core.telegram.org/mtproto/auth_key
    https://core.telegram.org/mtproto/samples-auth_key
    这种方法将使您更好地理解和介绍整个 Telegram API 中使用的原语,并可能帮助您开始组织您自己的一组函数和例程来处理您在下一步中需要的 - 实现 API 的其他功能,因为生成 AuthKey 只是开始。
    步骤 1
    所有通信都是通过 TCP 进行的 - 一旦您获得了唯一的 api_id ( https://core.telegram.org/api/obtaining_api_id#obtaining-api-id ),您将发现以下 IP 广告用于测试: 149.154.167.40:433 此时不需要 api_id 来生成 AuthKey
    设置发送/接收 TCP 处理循环的首选方法
    我拥有的是一个私有(private)的 SendData,它只是将一个字节发送到连接到上面给定 IP 地址的实时套接字

    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
    
    最后,对于这一步,我们需要一个 TcpPack() 方法来帮助我们以 Telegram 期望的格式填充我们的数据 - 请参阅下面的代码和注释
    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
    
    第 2 步
    通过基本的 TCP 发送/接收例程设置,我们可以开始准备要发送到电报的数据包,并拥有处理接收到的特定响应的子例程 - 进程响应(数据)
    接下来我们需要了解的是 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) 方法来处理每种类型
    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
    
    目前只有 未加密消息 是必须的
    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
    
    第 3 步
    现在我们按照 https://core.telegram.org/mtproto/auth_key 中概述的一系列步骤进行操作
  • https://core.telegram.org/mtproto/auth_key#dh-exchange-initiation

    1. Client sends query to server

    req_pq#60469778 nonce:int128 = ResPQ The value of nonce is selected randomly by the client (random number) and identifies the client within this communication. Following this step, it is known to all.

    1. Server sends response of the form

    resPQ#05162463 nonce:int128 server_nonce:int128 pq:string server_public_key_fingerprints:Vector long = ResPQ


    我的方法很简单:
    Sub RequestPQAuthorization()
        Send(MTProto.req_pq)
    End Sub
    
    在一个名为 MTProto 的类中,我根据交换的每个步骤的需要实现了一组共享函数。每种方法都只是建立一个加密的数据结构,将在需要时按上述方式发送
    我们从:开始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)常量 ZERO_TICK = 621355968000000000 -- 即 1970-01-01T00:00:00Z(1970 年 1 月 1 日,UTC 时间上午 12:00)
    现在我们的进程响应方法来自 步骤 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
    
    到目前为止,收到的每个响应都有一个 message_type 代码。
    我们可以打开它并确定如何处理每个。我们现在需要处理 resPQ。
    我所做的是创建一组类,每个类都处理特定的响应类型
    ''' <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
    
    每个都基于这个简单的对象
    Public MustInherit Class TLObject
        Public Shared Property ClassId As String
        Public MustOverride Overrides Function ToString() As String
    End Class
    
    在此基础上,我们处理步骤 3 和 4

    Proof of work 3) Client decomposes pq into prime factors such that p < q.

    This starts a round of Diffie-Hellman key exchanges.

    Presenting proof of work; Server authentication 4) Client sends query to server

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


    这是在这里发起的RequestDHKeyExchange(New resPQ(r.message_data))在我的 ProcessResponse上面的套路
    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
    
    您可以使用自己的 Prime-Decomposition 实现来替换这一行 Dim pp = New PrimeProduct(r.pq)这是我如何使用 学习的示例波拉德布伦特 (Pollard Rho Brent 整数分解)https://stackoverflow.com/a/31978350/44080
    好的,如果您可以跟进到这一点,您对我如何逐步分解 AuthKey 实现有一个大致的了解。
    您应该能够完成剩余的步骤 5-9。我要打很多字...
    如果到目前为止这个答案对任何人都有帮助,那么我会花时间组织和发布剩余的部分。
    我相信您在此过程中积累的例程和知识应该为您提供从头开始理解和实现您自己的独立 Telegram API 代码所需的工具。
    已完成交互转储
    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
    
    ....
    问候。

    关于php - 如何使用 Telegram API 实现授权?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30661644/

    相关文章:

    algorithm - 使用存在量词的高效联合查找?

    c# - 我预计此算法检查元音的速度会很慢

    javascript - 在jQuery插件内部使用YouTube Iframe API获取状态

    android - 如何在 Android 中使用 woocommerce Api 改造实现 OAuth 1.0a

    php - 如何在运行时读取 php.ini 值?

    php - 需要一个正则表达式来将 css 类添加到第一个和最后一个列表项

    algorithm - 我可以使用什么算法在图像上应用鱼眼失真?

    api - 微服务 Http 状态代码

    Php mysql只更新空列

    PHP 表单输入过滤