Trying to go through step 4.
Generatin encrypted_data But server doesn't answer ((
This commit is contained in:
parent
66a5577ab9
commit
c01bb7871b
91
mtproto.py
91
mtproto.py
|
@ -20,7 +20,7 @@ def vis(bs):
|
||||||
symbols_in_one_line = 8
|
symbols_in_one_line = 8
|
||||||
n = len(bs) // symbols_in_one_line
|
n = len(bs) // symbols_in_one_line
|
||||||
for i in range(n):
|
for i in range(n):
|
||||||
print(" ".join(["%02X" % b for b in bs[i*symbols_in_one_line:(i+1)*symbols_in_one_line]])) # for every 8 symbols line
|
print(str(i*symbols_in_one_line)+" | "+" ".join(["%02X" % b for b in bs[i*symbols_in_one_line:(i+1)*symbols_in_one_line]])) # for every 8 symbols line
|
||||||
print(" ".join(["%02X" % b for b in bs[(i+1)*symbols_in_one_line:]])+"\n") # for last line
|
print(" ".join(["%02X" % b for b in bs[(i+1)*symbols_in_one_line:]])+"\n") # for last line
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,7 +47,6 @@ class TlMethod:
|
||||||
self.params = json_dict['params']
|
self.params = json_dict['params']
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TL:
|
class TL:
|
||||||
def __init__(self, filename):
|
def __init__(self, filename):
|
||||||
with open(filename, 'r') as f:
|
with open(filename, 'r') as f:
|
||||||
|
@ -61,7 +60,7 @@ class TL:
|
||||||
for elem in self.constructors:
|
for elem in self.constructors:
|
||||||
z = TlConstructor(elem)
|
z = TlConstructor(elem)
|
||||||
self.constructor_id[z.id] = z
|
self.constructor_id[z.id] = z
|
||||||
self.constructor_type[z.type] = z
|
self.constructor_type[z.predicate] = z
|
||||||
|
|
||||||
self.methods = TL_dict['methods']
|
self.methods = TL_dict['methods']
|
||||||
self.method_id = {}
|
self.method_id = {}
|
||||||
|
@ -75,37 +74,63 @@ class TL:
|
||||||
## Loading TL_schema
|
## Loading TL_schema
|
||||||
tl = TL("TL_schema.JSON")
|
tl = TL("TL_schema.JSON")
|
||||||
|
|
||||||
def serialize(bytes_io, type_, value):
|
|
||||||
|
def serialize_obj(bytes_io, type_, **kwargs):
|
||||||
|
try:
|
||||||
|
tl_constructor = tl.constructor_type[type_]
|
||||||
|
except KeyError:
|
||||||
|
raise Exception("Could not extract type: %s" % type_)
|
||||||
|
bytes_io.write(struct.pack('<i', tl_constructor.id))
|
||||||
|
for arg in tl_constructor.params:
|
||||||
|
serialize_param(bytes_io, type_=arg['type'], value=kwargs[arg['name']])
|
||||||
|
|
||||||
|
|
||||||
|
def serialize_method(bytes_io, type_, **kwargs):
|
||||||
|
try:
|
||||||
|
tl_method = tl.method_name[type_]
|
||||||
|
except KeyError:
|
||||||
|
raise Exception("Could not extract type: %s" % type_)
|
||||||
|
bytes_io.write(struct.pack('<i', tl_method.id))
|
||||||
|
for arg in tl_method.params:
|
||||||
|
serialize_param(bytes_io, type_=arg['type'], value=kwargs[arg['name']])
|
||||||
|
|
||||||
|
|
||||||
|
def serialize_param(bytes_io, type_, value):
|
||||||
if type_ == "int":
|
if type_ == "int":
|
||||||
assert isinstance(value, int)
|
assert isinstance(value, int)
|
||||||
bytes_io.write(struct.pack('<i', value))
|
bytes_io.write(struct.pack('<i', value))
|
||||||
if type_ == "int128":
|
elif type_ == "long":
|
||||||
|
assert isinstance(value, int)
|
||||||
|
bytes_io.write(struct.pack('<q', value))
|
||||||
|
elif type_ in ["int128", "int256"]:
|
||||||
assert isinstance(value, bytes)
|
assert isinstance(value, bytes)
|
||||||
bytes_io.write(struct.pack('<16s', value))
|
bytes_io.write(value)
|
||||||
|
elif type_ == 'string' or 'bytes':
|
||||||
|
l = len(value)
|
||||||
|
if l < 254: # short string format
|
||||||
|
bytes_io.write(int.to_bytes(l, 1, 'little')) # 1 byte of string
|
||||||
|
bytes_io.write(value) # string
|
||||||
|
bytes_io.write(b'\x00'*((-l-1) % 4)) # padding bytes
|
||||||
|
else:
|
||||||
|
bytes_io.write(b'\xfe') # byte 254
|
||||||
|
bytes_io.write(int.to_bytes(l, 3, 'little')) # 3 bytes of string
|
||||||
|
bytes_io.write(value) # string
|
||||||
|
bytes_io.write(b'\x00'*(-l % 4)) # padding bytes
|
||||||
|
|
||||||
def deserialize(bytes_io, type_=None, subtype=None):
|
def deserialize(bytes_io, type_=None, subtype=None):
|
||||||
|
"""
|
||||||
|
:type bytes_io: io.BytesIO object
|
||||||
|
"""
|
||||||
assert isinstance(bytes_io, io.BytesIO)
|
assert isinstance(bytes_io, io.BytesIO)
|
||||||
|
|
||||||
# Built-in bare types
|
# Built-in bare types
|
||||||
if type_ == 'int':
|
if type_ == 'int': x = struct.unpack('<i', bytes_io.read(4))[0]
|
||||||
x = struct.unpack('<i', bytes_io.read(4))[0]
|
elif type_ == '#': x = struct.unpack('<I', bytes_io.read(4))[0]
|
||||||
elif type_ == '#':
|
elif type_ == 'long': x = struct.unpack('<q', bytes_io.read(8))[0]
|
||||||
x = struct.unpack('<I', bytes_io.read(4))[0]
|
elif type_ == 'double': x = struct.unpack('<d', bytes_io.read(8))[0]
|
||||||
elif type_ == 'long':
|
elif type_ == 'int128': x = bytes_io.read(16)
|
||||||
x = struct.unpack('<q', bytes_io.read(8))[0]
|
elif type_ == 'int256': x = bytes_io.read(32)
|
||||||
elif type_ == 'double':
|
elif type_ == 'string' or type_ == 'bytes':
|
||||||
x = struct.unpack('<d', bytes_io.read(8))[0]
|
|
||||||
elif type_ == 'int128':
|
|
||||||
t = struct.unpack('<16s', bytes_io.read(16))[0]
|
|
||||||
x = int.from_bytes(t, 'little')
|
|
||||||
elif type_ == 'int256':
|
|
||||||
t = struct.unpack('<32s', bytes_io.read(32))[0]
|
|
||||||
x = int.from_bytes(t, 'little')
|
|
||||||
elif type_ == 'bytes':
|
|
||||||
l = int.from_bytes(bytes_io.read(1), 'little')
|
|
||||||
x = bytes_io.read(l)
|
|
||||||
bytes_io.read(-(l+1) % 4) # skip padding bytes
|
|
||||||
elif type_ == 'string':
|
|
||||||
l = int.from_bytes(bytes_io.read(1), 'little')
|
l = int.from_bytes(bytes_io.read(1), 'little')
|
||||||
assert l <= 254
|
assert l <= 254
|
||||||
if l == 254:
|
if l == 254:
|
||||||
|
@ -127,7 +152,7 @@ def deserialize(bytes_io, type_=None, subtype=None):
|
||||||
i = struct.unpack('<i', bytes_io.read(4))[0] # read type ID
|
i = struct.unpack('<i', bytes_io.read(4))[0] # read type ID
|
||||||
try:
|
try:
|
||||||
tl_elem = tl.constructor_id[i]
|
tl_elem = tl.constructor_id[i]
|
||||||
except:
|
except KeyError:
|
||||||
raise Exception("Could not extract type: %s" % type_)
|
raise Exception("Could not extract type: %s" % type_)
|
||||||
base_boxed_types = ["Vector t", "Int", "Long", "Double", "String", "Int128", "Int256"]
|
base_boxed_types = ["Vector t", "Int", "Long", "Double", "String", "Int128", "Int256"]
|
||||||
if tl_elem.type in base_boxed_types:
|
if tl_elem.type in base_boxed_types:
|
||||||
|
@ -210,16 +235,10 @@ class Session:
|
||||||
|
|
||||||
def method_call(self, method, **kwargs):
|
def method_call(self, method, **kwargs):
|
||||||
z=io.BytesIO()
|
z=io.BytesIO()
|
||||||
tl_method = tl.method_name[method]
|
serialize_method(z, method, **kwargs)
|
||||||
z.write(struct.pack('<i', tl_method.id))
|
|
||||||
for param in tl_method.params:
|
|
||||||
serialize(bytes_io=z, value=kwargs[param['name']], type_=param['type'])
|
|
||||||
self.send_message(z.getvalue())
|
self.send_message(z.getvalue())
|
||||||
server_answer = self.recv_message()
|
server_answer = self.recv_message()
|
||||||
|
if server_answer is not None:
|
||||||
return deserialize(io.BytesIO(server_answer))
|
return deserialize(io.BytesIO(server_answer))
|
||||||
|
else:
|
||||||
class Telegram:
|
raise Exception("Server not answered")
|
||||||
global tl
|
|
||||||
def connect(self, ip, port):
|
|
||||||
self.session = Session(ip, port)
|
|
||||||
|
|
49
testing.py
49
testing.py
|
@ -1,8 +1,10 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import mtproto
|
import mtproto
|
||||||
import os
|
import os, io
|
||||||
import prime
|
import prime
|
||||||
import configparser
|
import configparser
|
||||||
|
from Crypto.Hash import SHA
|
||||||
|
from Crypto.PublicKey import RSA
|
||||||
|
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
config.read('credentials')
|
config.read('credentials')
|
||||||
|
@ -10,9 +12,50 @@ ip = config['App data']['ip_address']
|
||||||
port = config['App data'].getint('port')
|
port = config['App data'].getint('port')
|
||||||
|
|
||||||
Session = mtproto.Session(ip, port)
|
Session = mtproto.Session(ip, port)
|
||||||
x = Session.method_call('req_pq', nonce=os.urandom(16))
|
client_nonce = os.urandom(16)
|
||||||
|
x = Session.method_call('req_pq', nonce=client_nonce)
|
||||||
|
|
||||||
PQ = int.from_bytes(x['pq'], 'big')
|
server_nonce = x['server_nonce']
|
||||||
|
public_key_fingerprint = x['server_public_key_fingerprints'][0]
|
||||||
|
PQ_bytes = x['pq']
|
||||||
|
|
||||||
|
PQ = int.from_bytes(PQ_bytes, 'big')
|
||||||
[p, q] = prime.primefactors(PQ)
|
[p, q] = prime.primefactors(PQ)
|
||||||
|
if p > q: (p, q) = (q, p) # swap values in way p<q
|
||||||
|
|
||||||
print("PQ = %d\np = %d, q = %d" % (PQ, p, q))
|
print("PQ = %d\np = %d, q = %d" % (PQ, p, q))
|
||||||
|
|
||||||
|
|
||||||
|
P_bytes = int.to_bytes(p, p.bit_length()//8+1, 'big')
|
||||||
|
Q_bytes = int.to_bytes(q, q.bit_length()//8+1, 'big')
|
||||||
|
|
||||||
|
f = open('rsa.pub', 'r')
|
||||||
|
key = RSA.importKey(f.read())
|
||||||
|
|
||||||
|
z= io.BytesIO()
|
||||||
|
|
||||||
|
new_nonce = os.urandom(32)
|
||||||
|
|
||||||
|
mtproto.serialize_obj(z, 'p_q_inner_data',
|
||||||
|
pq=PQ_bytes,
|
||||||
|
p=P_bytes,
|
||||||
|
q=Q_bytes,
|
||||||
|
nonce=client_nonce,
|
||||||
|
server_nonce=server_nonce,
|
||||||
|
new_nonce=new_nonce)
|
||||||
|
data = z.getvalue()
|
||||||
|
|
||||||
|
sha_digest = SHA.new(data).digest()
|
||||||
|
random_bytes = os.urandom(255-len(data)-len(sha_digest))
|
||||||
|
to_encrypt = sha_digest + data + random_bytes
|
||||||
|
encrypted_data = key.encrypt(to_encrypt, 0)[0]
|
||||||
|
|
||||||
|
z = Session.method_call('req_DH_params',
|
||||||
|
nonce=client_nonce,
|
||||||
|
server_nonce=server_nonce,
|
||||||
|
p=P_bytes,
|
||||||
|
q=Q_bytes,
|
||||||
|
public_key_fingerprint=public_key_fingerprint,
|
||||||
|
encrypted_data=encrypted_data)
|
||||||
|
|
||||||
|
print(z)
|
Loading…
Reference in New Issue
Block a user