Deconstruct & comment this private_key MPI parser.

master
Ethan Dalool 2020-03-09 15:08:11 -07:00
parent 2ba447ebad
commit f1047898e8
2 changed files with 15 additions and 5 deletions

View File

@ -104,6 +104,11 @@ def str_to_a32(b):
def mpi_to_int(s): def mpi_to_int(s):
'''
A Multi-precision integer is encoded as a series of bytes in big-endian
order. The first two bytes are a header which tell the number of bits in
the integer. The rest of the bytes are the integer.
'''
return int(binascii.hexlify(s[2:]), 16) return int(binascii.hexlify(s[2:]), 16)
def extended_gcd(a, b): def extended_gcd(a, b):

View File

@ -1,3 +1,4 @@
import math
import re import re
import json import json
import logging import logging
@ -119,13 +120,17 @@ class Mega:
) )
private_key = a32_to_str(rsa_private_key) private_key = a32_to_str(rsa_private_key)
# The private_key contains 4 MPI integers concatenated together.
rsa_private_key = [0, 0, 0, 0] rsa_private_key = [0, 0, 0, 0]
for i in range(4): for i in range(4):
l = int( # An MPI integer has a 2-byte header which describes the number
((private_key[0]) * 256 + (private_key[1]) + 7) / 8 # of bits in the integer.
) + 2 bitlength = (private_key[0] * 256) + private_key[1]
rsa_private_key[i] = mpi_to_int(private_key[:l]) bytelength = math.ceil(bitlength / 8)
private_key = private_key[l:] # Add 2 bytes to accommodate the MPI header
bytelength += 2
rsa_private_key[i] = mpi_to_int(private_key[:bytelength])
private_key = private_key[bytelength:]
encrypted_sid = mpi_to_int(base64_url_decode(resp['csid'])) encrypted_sid = mpi_to_int(base64_url_decode(resp['csid']))
rsa_decrypter = RSA.construct( rsa_decrypter = RSA.construct(