Td: What are the correct server public keys?

Created on 20 May 2018  路  5Comments  路  Source: tdlib/td

I'm trying to follow the auth_key tutorial on https://core.telegram.org/mtproto/auth_key which states that:

server_public_key_fingerprints is a list of public RSA key fingerprints (64 lower-order bits of SHA1 (server_public_key);

I can't however seem to find a matching server key for the fingerprint the server gives me back.

In response to req_pq_multi from 49.154.175.10:443 I get two fingerprints;

00000050  02 00 00 00 02 9f 4b a1  6d 10 92 96 21 6b e8 6c  |......K.m...!k.l|
00000060  02 2b b4 c3 8e 30 c9 e7                           |.+...0..|

Or more precisely 029f4ba16d109296 and 216be86c022bb4c3


The MTProto description states:

The application has a built-in public server key which can be used to verify a signature but cannot be used to sign messages.

So, assuming that this "built-in public server key" is what is fingerprinted here, I took a guess at trying out the keys in td/telegram/net/PublicRsaKeyShared.cpp using:

cat <pemkeyfile> | openssl base64 -d | openssl sha1 -hex

However, none of them match any of the fingerprints:

server_old.rsa:
(stdin)= 585bee78ec480df581633949b2afe8b3ac40f0d8
server_1.rsa:
(stdin)= 05de4db8d8fad362a6481770192385e558c73fe6
server_2.rsa:
(stdin)= b6158b9aef24f05aad3b7a3a711a5ce3016942dd
server_3.rsa:
(stdin)= 68d8b89daac76cfc6420e360c24a3c34fda4955d
server_4.rsa:
(stdin)= 1ac4948a650ae1063406812dad434befe842b3a1

(openssl rsa -RSAPublicKey_in -in <pemfile> | openssl base64 -d | openssl sha1 -hex doesn't match either)

So did the algorithm change in the meantime? Am I looking in the wrong place for the keys?
Is some other magic required for hashing?

Thanks for any pointers.

Most helpful comment

No, algorithm wasn't changed, you are looking in the right place, and yes, some magic is required for hashing. The whole sentence from documentation is "server_public_key_fingerprints is a list of public RSA key fingerprints (64 lower-order bits of SHA1 (server_public_key); the public key is represented as a bare type rsa_public_key n:string e:string = RSAPublicKey, where, as usual, n and 械 are numbers in big endian format serialized as strings of bytes, following which SHA1 is computed) received by the server."
So you need to TL-serialize n and e and calculate sha1 from that serialization. You can find implementation of that here.

All 5 comments

No, algorithm wasn't changed, you are looking in the right place, and yes, some magic is required for hashing. The whole sentence from documentation is "server_public_key_fingerprints is a list of public RSA key fingerprints (64 lower-order bits of SHA1 (server_public_key); the public key is represented as a bare type rsa_public_key n:string e:string = RSAPublicKey, where, as usual, n and 械 are numbers in big endian format serialized as strings of bytes, following which SHA1 is computed) received by the server."
So you need to TL-serialize n and e and calculate sha1 from that serialization. You can find implementation of that here.

Thanks for the answer @levlam . The implementation you point to is still at a pretty abstract layer, and I'd like to get a more down-to-earth feel of it.

So I've tried now:

  1. sha1(BN_bn2hex(n), BN_bn2hex(e))
  2. sha1(BN_bn2bin(n), BN_bn2bin(e))

... both with and without prefixing the data to be hashed with the "name"; 4 bytes crc32("rsa_public_key n:string e:string = RSAPublicKey") - it's not entirely clear to me when I have to add this prefix.

As I assume 1. is not correct anyway, I've included only the results of 2 sprintf("%02x",...). with and without name against the "old" certificate below:

HASH:
5fa5ecd1bbd6779ae616bafec2c84a81ba0b1be6
DATA:
c150023e2f70db7985ded064759cfecf0af328e69a41daf4d6f01b538135a6f91f8f8b2a0ec9ba9720ce352efcf6c5680ffc424bd634864902de0b4bd6d49f4e580230e3ae97d95c8b19442b3c0a10d8f5633fecedd6926a7f6dab0ddb7d457f9ea81b8465fcd6fffeed114011df91c059caedaf97625f6c96ecc74725556934ef781d866b34f011fce4d835a090196e9a5f0e4449af7eb697ddb9076494ca5f81104a305b6dd27665722c46b60e5df680fb16b210607ef217652e60236c255f6a28315f4083a96791d7214bf64c1df4fd0db1944fb26a2a57031b32eee64ad15a8ba68885cde74a5bfc920f6abf59ba5c75506373e7130f9042da922179251f010001

HASH:
7ff0120b13c353854ebd6f09f3d8166e5f87b702
DATA:
76cb197ac150023e2f70db7985ded064759cfecf0af328e69a41daf4d6f01b538135a6f91f8f8b2a0ec9ba9720ce352efcf6c5680ffc424bd634864902de0b4bd6d49f4e580230e3ae97d95c8b19442b3c0a10d8f5633fecedd6926a7f6dab0ddb7d457f9ea81b8465fcd6fffeed114011df91c059caedaf97625f6c96ecc74725556934ef781d866b34f011fce4d835a090196e9a5f0e4449af7eb697ddb9076494ca5f81104a305b6dd27665722c46b60e5df680fb16b210607ef217652e60236c255f6a28315f4083a96791d7214bf64c1df4fd0db1944fb26a2a57031b32eee64ad15a8ba68885cde74a5bfc920f6abf59ba5c75506373e7130f9042da922179251f010001

They still don't match, so I'm still doing something wrong.

The certificate in question:

$ openssl asn1parse -in keys/server_old.rsa 
    0:d=0  hl=4 l= 266 cons: SEQUENCE          
    4:d=1  hl=4 l= 257 prim: INTEGER           :C150023E2F70DB7985DED064759CFECF0AF328E69A41DAF4D6F01B538135A6F91F8F8B2A0EC9BA9720CE352EFCF6C5680FFC424BD634864902DE0B4BD6D49F4E580230E3AE97D95C8B19442B3C0A10D8F5633FECEDD6926A7F6DAB0DDB7D457F9EA81B8465FCD6FFFEED114011DF91C059CAEDAF97625F6C96ECC74725556934EF781D866B34F011FCE4D835A090196E9A5F0E4449AF7EB697DDB9076494CA5F81104A305B6DD27665722C46B60E5DF680FB16B210607EF217652E60236C255F6A28315F4083A96791D7214BF64C1DF4FD0DB1944FB26A2A57031B32EEE64AD15A8BA68885CDE74A5BFC920F6ABF59BA5C75506373E7130F9042DA922179251F
  265:d=1  hl=2 l=   3 prim: INTEGER           :010001

I also realize that this isn't an "issue" as such. Is there another forum to post questions like these concerning Telegram?

@nolash, you don't need to append "name", because documentation says "bare type", which exactly means without "name": https://core.telegram.org/mtproto/serialize#boxed-and-bare-types. But you need to serialize strings as stated in https://core.telegram.org/mtproto/serialize#base-types.

@levlam Got it! And got the right hash. Thanks for your clarifications.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mossaudi picture mossaudi  路  3Comments

devxpy picture devxpy  路  5Comments

Invision70 picture Invision70  路  3Comments

isopen picture isopen  路  5Comments

sh-a-v picture sh-a-v  路  3Comments