# RSA private key format for Mega

I've been trying to reverse engineer Mega's (mega.co.nz) API calls. And stopped on the step where client needs to decrypt session id with provided RSA key. I can get key data, but I have no idea how to convert this data into actual key.

Here is my Base64 encoded private key:

BACLkf9qj1yTiX+Jrc7nlp8GMbTh9XnksdQgImr1kRazEsWy28hgOOqjPrsUTe0HtG7UKJzltzBd
1cDQI40qWmmCfsRmKiwNJazfCpDgI21LMveudU9O5djvqgGz8YNVVaOhg//IFAppnb6NHlY51qnP
tEJef47K/2rWMFXUZ8DjrQQA7TTQIUYutrF83GidNT2Od1d+v5hrcCLKzjBYbUIIX1ntI3gFmJyu
9sZ3mmFTuVvqz547cc2d++7Od7s/hUGZvZEKBQgD4McH/i2kzsuiWCLsyJ74PcQTcQnkZeHsV53T
6s4pAUV9yyfz0VYu+84W1SKclSnhAkZNOFDz56oG7BQZqkP4uJoX6Uf3woikjDdGEYMh1nAJj5KR
G+8WhrvUftSCOMJdgfoFpZZGAIZfvrBjRaevvceh10YzNb8l+fd3ucF9v9IPj3/XMMoWNltDm7YC
gA1PZj6aU3hum47PZu2oQnsCtSER004lwHC28rHgJP2QVl22W7A7hd7/Tn/MMYXmhC8sKu6cVVew
rx0T3yBVmpILpQ2MRFHHwucXBQLPfvgxiC/c1Pnr1GqZf6FgpZSSbUhLkkfpchRyQyzhNaA5NhsN
V2+PCCEEAJTTXts5/Emt/84BEzXC5gg7o0kdR0Z3NxnkLTILpY0IxhnRA6wxO4pDRbsqc85DzSnO
DWOBnGYf2A+sLAgoGFGBZ53QaI90LS0tLS0tLS0=


From what I understand, it consists of four parts(big integers): p, q, d, u. I know that to get generate private key we need modulus(p*q) and private exponent (d)

So I'm wondering, is there standard private key format for this key, or they just using some internal encoding?

-

The format is not an official standard, but it is pretty straight forward. There are indeed 4 fields, in order $p$, $q$, $d$ and $u$ (I'm not quite sure what the function of the $u$ is?, it's not the CRT representation that is common in standards).

First decode the base64: it starts with 0x04 0x00 0x8b 0x91 0xff 0x6a 0x8f 0x5c..

Every number is encoded as a big-endian 2 byte number that denotes the number of bits (So here 0x400 = 1024), so we then know the number of bytes (so here 0x80 bytes) that then follows and this is just a bigendian number ($p$). After these bytes we get the second length field (0x400 again) followed by 0x80 bytes (for $q$), a length 0x7fe = 2046 bits so 0x100 bytes that encode $d$ (it makes sense that this should be roughly twice the number of bits of $p$ and $q$, as it is of order $(p-1)(q-1)$) and the last $u$ is again 0x400 = 1024 bits, and after this number we get 0x2d = '-' characters as padding.

Normally these private keys are ASN.1-encoded (e.g. PEM format), and Microsoft has its own format in Windows, etc. Many such encodings are just a decorated version of the length followed by data of that length format, so this is pretty easy to figure out.

Take a bignum library (I use GMP, normally) and try to convert the bytes to numbers and check primality etc etc. to try to verify this.

-
without decoding your b64, have a look at the api_setrsa(privk, pubk) function call located in crypto_0.js, thats were it gets encrypted and stored. it is called from keygen_0.js:
api_setrsa([rsa_p,rsa_q,rsa_d,rsa_u],[rsa_pq,rsa_e]);