Fix v1 login by calculating public exp instead of hardcode 257.
The code was using a hardcoded 257 as the RSA public exponent, but it was raising RSA Invalid Construct. From reading MEGA's webclient js I found that the public exponent sometimes defaults to 257, but in other cases is calculated from a modular inverse on the private exponent and phi=p-1*q-1.
This commit is contained in:
parent
f1047898e8
commit
1e96d9b435
1 changed files with 22 additions and 8 deletions
|
@ -21,7 +21,8 @@ from .errors import ValidationError, RequestError
|
||||||
from .crypto import (
|
from .crypto import (
|
||||||
a32_to_base64, encrypt_key, base64_url_encode, encrypt_attr, base64_to_a32,
|
a32_to_base64, encrypt_key, base64_url_encode, encrypt_attr, base64_to_a32,
|
||||||
base64_url_decode, decrypt_attr, a32_to_str, get_chunks, str_to_a32,
|
base64_url_decode, decrypt_attr, a32_to_str, get_chunks, str_to_a32,
|
||||||
decrypt_key, mpi_to_int, stringhash, prepare_key, make_id, makebyte
|
decrypt_key, mpi_to_int, stringhash, prepare_key, make_id, makebyte,
|
||||||
|
modular_inverse
|
||||||
)
|
)
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -132,14 +133,27 @@ class Mega:
|
||||||
rsa_private_key[i] = mpi_to_int(private_key[:bytelength])
|
rsa_private_key[i] = mpi_to_int(private_key[:bytelength])
|
||||||
private_key = private_key[bytelength:]
|
private_key = private_key[bytelength:]
|
||||||
|
|
||||||
|
first_factor_p = rsa_private_key[0]
|
||||||
|
second_factor_q = rsa_private_key[1]
|
||||||
|
private_exponent_d = rsa_private_key[2]
|
||||||
|
# In MEGA's webclient javascript, they assign [3] to a variable
|
||||||
|
# called u, but I do not see how it corresponds to pycryptodome's
|
||||||
|
# RSA.construct and it does not seem to be necessary.
|
||||||
|
rsa_modulus_n = first_factor_p * second_factor_q
|
||||||
|
phi = (first_factor_p - 1) * (second_factor_q - 1)
|
||||||
|
public_exponent_e = modular_inverse(private_exponent_d, phi)
|
||||||
|
|
||||||
|
rsa_components = (
|
||||||
|
rsa_modulus_n,
|
||||||
|
public_exponent_e,
|
||||||
|
private_exponent_d,
|
||||||
|
first_factor_p,
|
||||||
|
second_factor_q,
|
||||||
|
)
|
||||||
|
rsa_decrypter = RSA.construct(rsa_components)
|
||||||
|
|
||||||
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_private_key[0] * rsa_private_key[1], 257,
|
|
||||||
rsa_private_key[2], rsa_private_key[0],
|
|
||||||
rsa_private_key[1]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
sid = '%x' % rsa_decrypter._decrypt(encrypted_sid)
|
sid = '%x' % rsa_decrypter._decrypt(encrypted_sid)
|
||||||
sid = binascii.unhexlify('0' + sid if len(sid) % 2 else sid)
|
sid = binascii.unhexlify('0' + sid if len(sid) % 2 else sid)
|
||||||
self.sid = base64_url_encode(sid[:43])
|
self.sid = base64_url_encode(sid[:43])
|
||||||
|
|
Loading…
Reference in a new issue