使用 Node.js AES CTR 加密并使用 PyCrypto 解密

问题描述 投票:0回答:2

好吧,基本上我在使用 Python 解密时遇到了问题。

我已经成功地使用 Node.js 加密/解密数据 - 使用“aes-128-ctr”,PyCrypto 也是如此,但是当我尝试使用 Node.js 加密并使用 Python 解密时,我得到了无效的解密文本。

Node.js 代码:

var key = "1234567890123456";
var cipher = crypto.createCipher("aes-128-ctr",key)
var ctext = cipher.update('asasasa','utf8','hex') +  cipher.final('hex')
console.log(ctext) // outputs: "f2cf6ecd8f"

Python代码:

counter = Counter.new(128)
cipher = AES.new("1234567890123456", AES.MODE_CTR, counter=counter)
cipher.decrypt("f2cf6ecd8f") // outputs: weird encoding characters

顺便说一下,我并不关心这种加密的安全级别,我更关心性能。

python node.js cryptography aes pycrypto
2个回答
3
投票

crypto.createCipher
获取密码并在内部使用
EVP_BytesToKey
从中导出密钥和 IV。与此相反,pycrypto 直接需要密钥和 IV。您需要在两侧使用完全相同的程序。

crypto.createCipher
绝不能与 CTR 模式一起使用,因为密钥和 IV 生成不是随机的。由于 CTR 模式是一种流模式,因此它始终会产生相同的密钥流,这可能使攻击者能够“仅”观察到使用相同密码加密的多个密文来推断出明文。这是可能的,因为由此产生的多次垫问题。 如果你必须使用CTR模式,那么你必须使用

crypto.createCipheriv

。如果您使用相同的密钥,则每次都必须使用不同的 IV。这就是为什么这实际上被称为 CTR 模式的随机数。对于 AES-CTR,96 位随机数是安全性和可能可加密明文大小之间的良好折衷方案。

var plaintext = 'asasasa'
var key = "1234567890123456" # don't use this one!
var nonce = crypto.randomBytes(12)
var iv = Buffer.concat([nonce, Buffer.alloc(4, 0)])
var cipher = crypto.createCipheriv("aes-128-ctr", key, iv)
var ciphertext = nonce.toString('hex') + cipher.update(plaintext,'utf8','hex') +  cipher.final('hex')
console.log(ciphertext)

输出示例:

5b88aeb265712b6c8bfa8dbd63012d1e52eb42

IV 不是秘密的,解密时必须使用完全相同的 IV。通常,它通过添加前缀与密文一起发送。然后在解密之前将其切掉:

ct = codecs.decode('5b88aeb265712b6c8bfa8dbd63012d1e52eb42', 'hex') # I'm using Python 3 counter = Counter.new(32, prefix=ct[:12], initial_value=0) cipher = AES.new("1234567890123456", AES.MODE_CTR, counter=counter) cipher.decrypt(ct[12:])

输出:

b'asasasa'

请记住,需要随机选择密钥。您可以生成随机密钥并将其以编码形式保存在源代码中(即十六进制)。如果您这样做,则不得将源代码或字节码提供给您不信任密钥的任何人。


0
投票

© www.soinside.com 2019 - 2024. All rights reserved.