2016-09-03 11:54:58 +03:00
|
|
|
# This file is based on TLSharp
|
2016-09-04 12:07:18 +03:00
|
|
|
# https://github.com/sochix/TLSharp/blob/master/TLSharp.Core/MTProto/Crypto/RSA.cs
|
2016-09-03 11:54:58 +03:00
|
|
|
from utils.binary_writer import BinaryWriter
|
|
|
|
import utils.helpers as utils
|
|
|
|
|
|
|
|
|
|
|
|
class RSAServerKey:
|
|
|
|
def __init__(self, fingerprint, m, e):
|
|
|
|
self.fingerprint = fingerprint
|
|
|
|
self.m = m
|
|
|
|
self.e = e
|
|
|
|
|
|
|
|
def encrypt(self, data, offset=None, length=None):
|
2016-09-04 12:07:18 +03:00
|
|
|
"""Encrypts the given data with the current key"""
|
2016-09-03 11:54:58 +03:00
|
|
|
if offset is None:
|
|
|
|
offset = 0
|
|
|
|
if length is None:
|
|
|
|
length = len(data)
|
|
|
|
|
|
|
|
with BinaryWriter() as writer:
|
|
|
|
# Write SHA
|
|
|
|
writer.write(utils.sha1(data[offset:offset+length]))
|
|
|
|
# Write data
|
|
|
|
writer.write(data[offset:offset+length])
|
|
|
|
# Add padding if required
|
|
|
|
if length < 235:
|
|
|
|
writer.write(utils.generate_random_bytes(235 - length))
|
|
|
|
|
|
|
|
cipher_text = utils.get_byte_array(
|
|
|
|
pow(int.from_bytes(writer.get_bytes(), byteorder='big'), self.e, self.m),
|
|
|
|
signed=False)
|
|
|
|
|
|
|
|
if len(cipher_text) == 256:
|
|
|
|
return cipher_text
|
|
|
|
|
|
|
|
else:
|
|
|
|
padding = bytes(256 - len(cipher_text))
|
|
|
|
return padding + cipher_text
|
|
|
|
|
|
|
|
|
|
|
|
class RSA:
|
|
|
|
_server_keys = {
|
|
|
|
'216be86c022bb4c3':
|
|
|
|
RSAServerKey('216be86c022bb4c3', int('C150023E2F70DB7985DED064759CFECF0AF328E69A41DAF4D6F01B538135A6F9'
|
|
|
|
'1F8F8B2A0EC9BA9720CE352EFCF6C5680FFC424BD634864902DE0B4BD6D49F4E'
|
|
|
|
'580230E3AE97D95C8B19442B3C0A10D8F5633FECEDD6926A7F6DAB0DDB7D457F'
|
|
|
|
'9EA81B8465FCD6FFFEED114011DF91C059CAEDAF97625F6C96ECC74725556934'
|
|
|
|
'EF781D866B34F011FCE4D835A090196E9A5F0E4449AF7EB697DDB9076494CA5F'
|
|
|
|
'81104A305B6DD27665722C46B60E5DF680FB16B210607EF217652E60236C255F'
|
|
|
|
'6A28315F4083A96791D7214BF64C1DF4FD0DB1944FB26A2A57031B32EEE64AD1'
|
|
|
|
'5A8BA68885CDE74A5BFC920F6ABF59BA5C75506373E7130F9042DA922179251F',
|
|
|
|
16), int('010001', 16))
|
|
|
|
}
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def encrypt(fingerprint, data, offset=None, length=None):
|
2016-09-04 12:07:18 +03:00
|
|
|
"""Encrypts the given data given a fingerprint"""
|
2016-09-03 11:54:58 +03:00
|
|
|
if fingerprint.lower() not in RSA._server_keys:
|
|
|
|
return None
|
|
|
|
|
|
|
|
key = RSA._server_keys[fingerprint.lower()]
|
|
|
|
return key.encrypt(data, offset, length)
|