我在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内部使用的是什么。我尝试了许多没有成功
masterkey[0:16].encode()
bytes(16)
答案 0 :(得分:3)
根据问题中的新信息进行更新:最好的办法是Nodejs使用的是默认计数器值。
加密和解密必须使用相同的计数器值。但是没有提供加密的计数器值,并且在解密时使用随机值,因此它永远不会起作用。
使用:crypto.createCipheriv(algorithm, key, iv)
其中iv
是随机计数器的初始值。
必须在加密时创建随机计数器值并将其保存,以便在解密时可以使用相同的初始计数器值。一种选择是在加密数据前加上计数器值,它不需要是保密的。然后在解密时,它可以从加密数据中分离出来并使用。
同样,当使用CTR模式时,相同的初始计数器值绝不能再次使用相同的键。
请参阅CTR mode
PyCrypto文档CTR mode:
MODE_CBC
密码链(CBC)。每个密文块取决于当前和所有先前的明文块。 需要初始化向量(IV)。IV是要发送到接收器的数据块。 IV可以公开,但必须由接收者进行身份验证,并且应该随机选择。)
IV是初始计数器值。
[Nodejs dociumewnrtation:Class: Cipher:
crypto.createCipheriv(algorithm, key, iv)
algorithm <string>
key <string> | <Buffer> | <TypedArray> | <DataView>
iv <string> | <Buffer> | <TypedArray> | <DataView>
使用给定的算法,密钥和初始化向量(iv)创建并返回一个Cipher对象。