NodeJS AES Encrypt Python Decrypt
I have a nodejs service that uses AES encryption on some data that needs to be decrypted in Python. No matter what I do I cannot make this to work. NodeJS code:
const algorithm = 'aes-128-ctr';
function encryptScript(data, key) {
const cipher = crypto.createCipher(algorithm, key);
let crypted = cipher.update(data, 'utf8', 'hex');
crypted += cipher.final('hex');
return crypted;
}
I have tried in Python:
counter = Counter.new(128)
cipher = AES.new(key, AES.MODE_CTR, counter=counter)
print cipher.decrypt(enc.decode("hex"))
But it is not working.
My first issue is that the Python code is not accepting keys that are longer than 32 bytes (and the Nodejs code does).
If I use NodeJS crypto module the decryption is working:
function decryptScript(data, key) {
const decipher = crypto.createDecipher(algorithm, key);
let dec = decipher.update(data, 'hex', 'utf8');
dec += decipher.final('utf8');
return dec;
}
I don't know what node is doing but it is probably related to some padding of the data.
How can I make it work?
(I will prefer a solution that will not require changes in the NodeJS code but only in the Python script).
Answer
CreateCipher
usesEVP_BytesToKey
to create a key and an IV from a password (what is called a key in the NodeJS-code is actually the password). Here is an implementation ofEVP_BytesToKey
in Python. The parameters to use are described in the documentation ofCreateCipher
: MD5, no salt, one iteration. In CTR-mode the IV is usually incremented with each block starting with a value to be defined.CreateCipher
uses as start value the IV determined withEVP_BytesToKey
. The functionality ofCreateCipher
can therefore be implemented in Python as follows:import hashlib from Crypto.Cipher import AES from Crypto.Util import Counter ... encrypted = '5e99b5190f12143c057f6bdd8625f958682e737c11e138a2f571c050313dbe1008347604c7c7e8bf506a0a' # Example # Generate key and iv keySize = 16 ivSize = 16 digest = hashlib.md5 salt = b'' password = b'123456' # Example iteration = 1 keyiv = EVP_BytesToKey(keySize, ivSize, digest, salt, password, iteration) key = keyiv[0] iv = keyiv[1] # Define counter nbits = 128 initial_value = int.from_bytes(iv, byteorder = 'big'); counter = Counter.new(nbits, initial_value = initial_value) # Decrypt cipher = AES.new(key, AES.MODE_CTR, counter = counter) decrypted = cipher.decrypt(bytes.fromhex(encrypted)) print("Decrypted: " + decrypted.decode('utf8'))
The ciphertext was generated with the NodeJS-code using the following input:
key = '123456'; data = 'The quick brown fox jumps over the lazy dog';
Note that
CreateCipher
is deprecated and should no longer be used, especially not in combination with the CTR-mode. InsteadCreateCipheriv
can be used. In CTR-mode, it is important that a key/IV-pair is used only once. Otherwise the security will be lost, see here.CreateCipher
doesn't provide randomization, i.e. the same password always generates the same key and IV and thus always the same keystream. Therefore, security is lost if the same password is used several times.CreateCipheriv
, on the other hand, expects a key and a random IV. Here a key can be used several times as long as the randomization of the IV ensures that key/value-pairs are not repeated, see here.
Related Questions
- → What are the pluses/minuses of different ways to configure GPIOs on the Beaglebone Black?
- → Django, code inside <script> tag doesn't work in a template
- → React - Django webpack config with dynamic 'output'
- → GAE Python app - Does URL matter for SEO?
- → Put a Rendered Django Template in Json along with some other items
- → session disappears when request is sent from fetch
- → Python Shopify API output formatted datetime string in django template
- → Can't turn off Javascript using Selenium
- → WebDriver click() vs JavaScript click()
- → Shopify app: adding a new shipping address via webhook
- → Shopify + Python library: how to create new shipping address
- → shopify python api: how do add new assets to published theme?
- → Access 'HTTP_X_SHOPIFY_SHOP_API_CALL_LIMIT' with Python Shopify Module