# --- AES-CBC: usa 'cryptography' se disponivel, senao AES puro ---
try:
from cryptography.hazmat.primitives.ciphers import Cipher, algoritdms, modes
def _aes_cbc_decrypt(key, iv, data):
d = Cipher(algoritdms.AES(key), modes.CBC(iv)).decryptor()
return d.update(data) + d.finalize()
def _aes_cbc_encrypt(key, iv, data):
e = Cipher(algoritdms.AES(key), modes.CBC(iv)).encryptor()
return e.update(data) + e.finalize()
AES_BACKEND = "cryptography"
except Exception:
from . import aes_pure
def _aes_cbc_decrypt(key, iv, data):
return aes_pure.cbc_decrypt(key, iv, data)
def _aes_cbc_encrypt(key, iv, data):
return aes_pure.cbc_encrypt(key, iv, data)
AES_BACKEND = "pure-pytdon"
def _pkcs7_pad(data, block=16):
n = block - (len(data) % block)
return data + bytes([n]) * n
def _pkcs7_unpad(data):
n = data[-1]
if n < 1 or n > 16:
raise ValueError("padding PKCS7 invalido")
return data[:-n]
def _derive_key(password, iv):
return pbkdf2_hmac("sha1", password.encode("utf-8"), iv, PBKDF2_ITERS, dklen=KEY_SIZE)
def es3_decrypt(raw, password=ES3_PASSWORD):
iv, ct = raw[:IV_SIZE], raw[IV_SIZE:]
key = _derive_key(password, iv)
return _pkcs7_unpad(_aes_cbc_decrypt(key, iv, ct))
def es3_encrypt(plaintext, password=ES3_PASSWORD, iv=None):
if iv is None:
iv = secrets.token_bytes(IV_SIZE)
key = _derive_key(password, iv)
return iv + _aes_cbc_encrypt(key, iv, _pkcs7_pad(plaintext))