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

时间:2017-07-09 13:07:13

标签: python node.js cryptography aes pycrypto

好的,基本上我遇到了用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

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

1 个答案:

答案 0 :(得分:1)

crypto.createCipher获取密码和EVP_BytesToKey从中获取密钥和IV,但pycrypto直接需要密钥和IV。您需要使用完全相同的程序。

crypto.createCipher绝不能与CTR模式一起使用,因为密钥和IV生成不是随机的。由于CTR模式是流模式,因此它将始终生成相同的密钥流,这可能使观察到使用相同密码加密的多个密文的攻击者能够推断出明文。这是可能的,因为产生了多次填充问题。

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

var key = "1234567890123456"
var iv = Buffer.concat([crypto.randomBytes(12), Buffer.alloc(4, 0)])
var cipher = crypto.createCipheriv("aes-128-ctr", key, iv)
var ctext = iv.toString('hex') + cipher.update('asasasa','utf8','hex') +  cipher.final('hex')
console.log(ctext)

示例输出:

5b88aeb265712b6c8bfa8dbd0000000063012d1e52eb42

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

ct = codecs.decode('5b88aeb265712b6c8bfa8dbd0000000063012d1e52eb42', '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[16:])

输出:

b'asasasa'

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