from Crypto.Cipher import AES
from Crypto.Hash import MD5
from Crypto.Random import get_random_bytes
import base64
def evp_bytes_to_key(password: bytes, salt: bytes, key_len: int, iv_len: int):
"""
OpenSSL-compatible key derivation (MD5)
"""
dtot = b""
d = b""
while len(dtot) < key_len + iv_len:
d = MD5.new(d + password + salt).digest()
dtot += d
return dtot[:key_len], dtot[key_len:key_len + iv_len]
def encrypt_for_cryptojs(plaintext: str, password: str) -> str:
plaintext_bytes = plaintext.encode("utf-8")
salt = get_random_bytes(8) # OpenSSL salt
key, iv = evp_bytes_to_key(password.encode("utf-8"), salt, 32, 16)
cipher = AES.new(key, AES.MODE_CBC, iv)
pad_len = 16 - (len(plaintext_bytes) % 16)
padded = plaintext_bytes + bytes([pad_len]) * pad_len
ciphertext = cipher.encrypt(padded)
openssl_bytes = b"Salted__" + salt + ciphertext
return base64.b64encode(openssl_bytes).decode("utf-8")