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.