Hello,
I’m trying a few things with Telegram’s MTProto.
Here is some doc related to the problem : https://core.telegram.org/mtproto/auth_key
With example : https://core.telegram.org/mtproto/samples-auth_key
What it’s supposed to do (making an authorization key) :
client -> server : req_pq#60469778
server -> client : resPQ#05162463
client -> server : req_DH_params#d712e4be # contains data encrypted with RSA
server -> client : server_DH_params_ok#d0e8075c # contains data enctrypted by AES256 IGE
... # more things, but we don't care
In req_DH_params#d712e4be
, the data is encrypted (RSA) by the client following :
data_with_hash := SHA1(data) + data + (any random bytes); such that the length equal 255 bytes;encrypted_data := RSA (data_with_hash, server_public_key); a
255-byte long number (big endian) is raised to the requisite power over
the requisite modulus, and the result is stored as a 256-byte number.
I know SHA1(data) for some data. I checked and it’s fine.
I have an other test checking if I’m able to properly decrypt in server_DH_params_ok#d0e8075c
: It works.
What happens :
Half of the time, the server returns an error (useless error, won’t help _ -404
) instead of server_DH_params_ok#d0e8075c
. For the other half, the message is accepted, server_DH_params_ok#d0e8075c
is returned but contains wrong values.
I suspect :
There may be something wrong while encrypting encrypted_data with RSA in req_DH_params#d712e4be
. I can’t check with the example since they padded with “random bytes”. Otherwise there’s something wrong about (de)serialization (they’re messing with both big and little endian and the documentation in not straightforward…).
The code (encrypting data in req_DH_params#d712e4be
only) :
data = :crypto.hash(:sha, data) <> data
padding = 255 - byte_size(data)
data_with_hash = data <> <<0::size(padding)-unit(8)>>
# encrypted_data := RSA (data_with_hash, server_public_key); a 255-byte long number (big endian)
# is raised to the requisite power over the requisite modulus, and the result is stored as a
# 256-byte number.
{e, n} = Crypto.get_key # get RSA public key components
encrypted_data = :crypto.mod_pow data_with_hash, e, n # data_with_hash^e % n
Do your see anything weird ?
Thank you !