Trying to implement these 2 functions from Python to Nodejs:
def encrypt(base64_data):
key = os.urandom(32)
encoded_key = base64.b16encode(key)
iv = ""
iv_vector = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
for i in iv_vector:
iv += chr(i)
ctr = Counter.new(128, initial_value=long(iv.encode("hex"), 16))
cipher = AES.new(key, AES.MODE_CTR, counter=ctr)
encrypted = cipher.encrypt(base64_data)
return encrypted, encoded_key
def decrypt(encrypted_data, orig_key):
key = base64.b16decode(orig_key)
iv = ""
iv_vector = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
for i in iv_vector:
iv += chr(i)
ctr = Counter.new(128, initial_value=long(iv.encode("hex"), 16))
cipher = AES.new(key, AES.MODE_CTR, counter=ctr)
decrypted = cipher.decrypt(encrypted_data)
return decrypted
This decrypt works (when I encrypt in Python, I manage to decrypt in node), but the opposite way fails. Any idea what is missing in the nodejs encrypt function?
// Not working
export const encrypt = (base64Data: string): {encryptedData: string, decryptionKey: string} => {
const key = randomBytes(32);
const encodedKey = key.toString('hex');
var iv = Buffer.from('00000000000000000000000000000000', 'hex');
var encipher = createCipheriv('aes-256-ctr', key, iv);
const x = Buffer.concat([
encipher.update(base64Data),
encipher.final()
]);
return {encryptedData: x.toString('base64'), decryptionKey: encodedKey};
}
// This works
export const decrypt = (base64Data: string, encodedKey: string) => {
const key = Buffer.from( encodedKey, 'hex')
var iv = Buffer.from('00000000000000000000000000000000', 'hex');
var decipher = createDecipheriv('aes-256-ctr', key, iv);
return Buffer.concat([
decipher.update(Buffer.from(base64Data)),
decipher.final()
]);
}
Advertisement
Answer
If the following points are taken into account, the encryption and decryption of both codes run in all possible combinations on my machine.
The Node-code must be changed in 2 places so that encryption and decryption are consistent: In the
return
-statement of theencrypt
-method,'00'+encodedKey
must be replaced by''+encodedKey
, otherwise the key for the decryption is one byte too long. In thereturn
-statement of thedecrypt
-method,Buffer.from(base64Data)
must be replaced byBuffer.from(base64Data, 'base64')
, since the ciphertext is Base64-encoded.The ciphertext in Python (returned by
encrypt
, passed todecrypt
) is a byte-array. The ciphertext in Node (returned fromencrypt
, passed todecrypt
) is a Base64-encoded string. Therefore a conversion is necessary here, e.g. in the Python-code.Node returns the key as a hex-string with lowercase letters, Python needs uppercase letters. Therefore, an appropriate conversion is necessary here, e.g. in tbe Python-code.