""" This module holds several utilities regarding RSA and server fingerprints. """ import os import struct from hashlib import sha1 try: import rsa import rsa.core except ImportError: rsa = None raise ImportError('Missing module "rsa", please install via pip.') from ..tl import TLObject # {fingerprint: Crypto.PublicKey.RSA._RSAobj} dictionary _server_keys = {} def get_byte_array(integer): """Return the variable length bytes corresponding to the given int""" # Operate in big endian (unlike most of Telegram API) since: # > "...pq is a representation of a natural number # (in binary *big endian* format)..." # > "...current value of dh_prime equals # (in *big-endian* byte order)..." # Reference: https://core.telegram.org/mtproto/auth_key return int.to_bytes( integer, (integer.bit_length() + 8 - 1) // 8, # 8 bits per byte, byteorder='big', signed=False ) def _compute_fingerprint(key): """ Given a RSA key, computes its fingerprint like Telegram does. :param key: the Crypto.RSA key. :return: its 8-bytes-long fingerprint. """ n = TLObject.serialize_bytes(get_byte_array(key.n)) e = TLObject.serialize_bytes(get_byte_array(key.e)) # Telegram uses the last 8 bytes as the fingerprint return struct.unpack('