I am using the below code to encrypt and decrypt in typescript:
const AES = require('crypto-js/aes');
const Utf8 = require('crypto-js/enc-utf8');
export const encrypt = (text, passphrase) => {
return AES.encrypt(text, passphrase).toString();
};
export const decrypt = (ciphertext, passphrase) => {
const bytes = AES.decrypt(ciphertext, passphrase);
const originalText = bytes.toString(Utf8);
return originalText;
};
Now, the encrypted message generated in Typescript is to be decrypted in a Python environment. I used Chat GPT to come up with a solution but it gave a different result.
In one of the StackOverflow answers it was mentioned that CryptoJS uses following method for AES encryption:
Now CryptoJs derives a 32 byte long encryption key for AES-256 and a
16 byte long initialization vector (iv) from the password, encrypts
the “Message” using this key, iv in AES mode CBC and (default) padding
Pkcs7.
I gave the above details as context to Chat GPT but that didn’t work either. My Python code uses cryptography library and the code looks like below.
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.scrypt import Scrypt
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import padding
from os import urandom
def derive_key_iv(password: str, salt: bytes, key_length=32, iv_length=16):
# Key derivation function
backend = default_backend()
kdf = Scrypt(
salt=salt,
length=key_length + iv_length,
n=2**14,
r=8,
p=1,
backend=backend
)
key_iv = kdf.derive(password.encode())
return key_iv[:key_length], key_iv[key_length:key_length+iv_length]
def encrypt(message: str, password: str):
salt = urandom(16) # Generate a random salt
key, iv = derive_key_iv(password, salt)
backend = default_backend()
cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend)
encryptor = cipher.encryptor()
padder = padding.PKCS7(algorithms.AES.block_size).padder()
padded_data = padder.update(message.encode()) + padder.finalize()
encrypted = encryptor.update(padded_data) + encryptor.finalize()
return salt + encrypted # prepend salt for use in decryption
def decrypt(token: bytes, password: str):
salt = token[:16] # Extract the salt from the beginning
encrypted_message = token[16:]
key, iv = derive_key_iv(password, salt)
backend = default_backend()
cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend)
decryptor = cipher.decryptor()
padded_plaintext = decryptor.update(encrypted_message) + decryptor.finalize()
unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()
plaintext = unpadder.update(padded_plaintext) + unpadder.finalize()
return plaintext.decode()
What can be done to get the correct decrypted result in python?