Skip to content
Advertisement

Translate encryption in python to node

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 the encrypt-method, '00'+encodedKey must be replaced by ''+encodedKey, otherwise the key for the decryption is one byte too long. In the return-statement of the decrypt-method, Buffer.from(base64Data) must be replaced by Buffer.from(base64Data, 'base64'), since the ciphertext is Base64-encoded.

  • The ciphertext in Python (returned by encrypt, passed to decrypt) is a byte-array. The ciphertext in Node (returned from encrypt, passed to decrypt) 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.

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement