将AES解密从CryptoJS移植到PyCrypto

时间:2015-09-11 14:50:04

标签: javascript python encryption encoding cryptojs

这是一个使用AES加密解码字符串的JavaScript部分

var p = 'some large string'
var s = 'Q05WTmhPSjlXM1BmeFd0UEtiOGg=' 
var y = CryptoJS.AES.decrypt({
    ciphertext: CryptoJS.enc.Base64.parse(p)
}, CryptoJS.enc.Base64.parse(s), {
    iv  CryptoJS.enc.Hex.parse("random")
});
var v = y.toString(CryptoJS.enc.Utf8)

我正在尝试使用导入AES在python中编写类似的解码函数。

任何人都可以帮我这个。我无法弄清楚js到python的所有等效代码。

我抬头看了这页 Python AES Decryption Routine (Code Help)

AES - Encryption with Crypto (node-js) / decryption with Pycrypto (python)

不确定他们的代码是否与我在这里的js相似

"y.toString(CryptoJS.enc.Utf8)"

这在python中意味着什么

我从其他来源尝试了类似的东西

from base64 import b64decode
from Crypto.Cipher import AES

iv = 'random'
key = 'Q05WTmhPSjlXM1BmeFd0UEtiOGg='
encoded = b64decode('some large string')

dec = AES.new(key=key, mode=AES.MODE_CBC, IV=iv)
value = dec.decrypt(encoded)

1 个答案:

答案 0 :(得分:2)

您的CryptoJS代码和Python代码存在多个问题。

密钥大小错误

您的密钥s仅包含20个字节(160位),它不构成AES的任何有效密钥大小,即128(10),192(12)和256位(14个回合) )。 CryptoJS将默默运行160位密钥的密钥安排,包含11轮, PyCrypto不支持(参见AES.c)。

你可以在CryptoJS中将密钥减少到128位:

var key = CryptoJS.enc.Base64.parse('Q05WTmhPSjlXM1BmeFd0UEtiOGg=');
key.sigBytes = 16;
key.clamp();

或在Python中:

key = b64decode('Q05WTmhPSjlXM1BmeFd0UEtiOGg=')[:16]

字符编码错误

您忘记从Python中的Base64字符串解码密钥,而您忘记从十六进制解码IV。字符'0'和字节0x00完全不同。有一种更简单的方法来定义全零IV:

iv = "\0"*16

没有取消暂停

CryptoJS默认使用PKCS#7填充,但PyCrypto不实现任何填充,只处理数据块大小的倍数。解密之后,你需要在Python中自己删除填充:

value = value[:value[-1]]

(最后一个字节确定填充字节的字节数)。更多关于here

其他注意事项:

你真的不应该将IV设置为静态值。应使用相同的密钥为每次加密随机生成IV。否则,您将失去语义安全性。由于IV不必是秘密的,你可以把它放在密文的前面,然后在解密之前把它切掉。