Decrypt AES-256-CTR payloads in Python when encrypted from Nodejs

时光怂恿深爱的人放手 提交于 2019-12-24 07:37:17

问题


I wrote an application in Nodejs that encrypts user passwords using AES-256-CTR :

const crypto = require('crypto')
const masterkey = 'azertyuiopazertyuiopazertyuiopaz'
const cipher = crypto.createCipher('aes-256-ctr', masterkey)
console.log(cipher.update('antoine', 'utf8', 'hex') + cipher.final('hex')) //=> 6415bc70ad76c6

It then gets persisted into a database and now I'm trying to decipher it from a Python script using PyCrypto like this :

masterkey = 'azertyuiopazertyuiopazertyuiopaz'
password = '6415bc70ad76c6'

from Crypto.Cipher import AES
import os
import binascii
counter = os.urandom(16)
# counter = bytes(16) # does not work
# counter = masterkey[0:16].encode() # does not work
cipher = AES.new(masterkey, AES.MODE_CTR, counter=lambda: counter)
print(cipher.decrypt(binascii.a2b_hex(password)))

But it gives me completely wrong results here.

Do you know what I am missing ?

EDIT

Thanks to zaph, it appears that the way my Javascript code encrypts data is insecure. I still have to figure out what IV is being used internally by Node. I've tried many without success

masterkey[0:16].encode()
bytes(16)

回答1:


Update based on new information in the question: The best bet is that Nodejs is using a default counter value.

The same counter value must be used for both encryption and decryption. But no counter value is provided on encryption and a random value is used on decryption so it can never work.

Use: crypto.createCipheriv(algorithm, key, iv) where iv is the random counter initial value.

It is necessary to create a random counter value on encryption and save it so that the same initial counter value can be used on decryption. One option is to prefix the encrypted data with the counter value, it does not need to be secret. Then on decryption it can be split from the encrypted data and used.

Also when using CTR mode the same initial counter value must never be use again with the same key.

See CTR mode

PyCrypto documentation CTR mode:

MODE_CBC
Cipher-Block Chaining (CBC). Each of the ciphertext blocks depends on the current and all previous plaintext blocks. An Initialization Vector (IV) is required.

The IV is a data block to be transmitted to the receiver. The IV can be made public, but it must be authenticated by the receiver and it should be picked randomly.)

The IV is the initial counter value.

[Nodejs dociumewnrtation: Class: Cipher:

crypto.createCipheriv(algorithm, key, iv)
    algorithm <string>  
    key <string> | <Buffer> | <TypedArray> | <DataView>
    iv <string> | <Buffer> | <TypedArray> | <DataView>

Creates and returns a Cipher object, with the given algorithm, key and initialization vector (iv).



来源:https://stackoverflow.com/questions/45426334/decrypt-aes-256-ctr-payloads-in-python-when-encrypted-from-nodejs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!