我在 Nodejs 中编写了一个应用程序,使用 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
然后它被保存到数据库中,现在我尝试使用 PyCrypto 从 Python 脚本中破译它,如下所示:
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)))
但它在这里给了我完全错误的结果。
你知道我错过了什么吗?
编辑
感谢 zaph,我的 Javascript 代码加密数据的方式似乎不安全。我仍然需要弄清楚 Node 内部使用的 IV 是什么。我尝试过很多次都没有成功
masterkey[0:16].encode()
bytes(16)
最佳答案
根据问题中的新信息进行更新:最好的选择是 Nodejs 使用默认计数器值。
加密和解密必须使用相同的计数器值。但加密时没有提供计数器值,解密时使用随机值,因此它永远无法工作。
使用:crypto.createCipheriv(algorithm, key, iv)
,其中iv
是随机计数器初始值。
有必要在加密时创建一个随机计数器值并保存它,以便在解密时可以使用相同的初始计数器值。一种选择是在加密数据前加上计数器值作为前缀,它不需要保密。然后在解密时可以将其从加密数据中分离出来并使用。
此外,在使用 CTR 模式时,同一 key 不得再次使用相同的初始计数器值。
参见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.)
IV 是初始计数器值。
[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).
关于python - 从 Nodejs 加密时解密 Python 中的 AES-256-CTR 有效负载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45426334/