将 AES 解密从 CryptoJS 移植到 PyCrypto
Porting AES decryption from CryptoJS to PyCrypto
这是一个 JavaScript 部分,它使用 AES 加密对字符串进行解码
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)
您的 CryptoJS 代码和 Python 代码存在多个问题。
密钥大小错误
您的密钥 s
仅包含 20 个字节(160 位),不构成 AES 的任何有效密钥大小,即 128 (10)、192 (12) 和 256 位(14 轮) ). CryptoJS 将默默地 运行 11 轮的 160 位密钥的密钥计划,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 = "[=12=]"*16
没有取消填充
CryptoJS 默认使用 PKCS#7 填充,但 PyCrypto 不实现任何填充,仅将数据处理为块大小的倍数。解密后,您需要自己删除 Python:
中的填充
value = value[:value[-1]]
(最后一个字节决定了有多少字节是填充字节)。更多关于 here.
其他注意事项:
您真的不应该将 IV 设置为静态值。应该为使用相同密钥的每次加密随机生成 IV。否则,您将失去语义安全性。由于IV不必是秘密的,你可以把它放在密文前面,然后在解密之前把它切掉。
这是一个 JavaScript 部分,它使用 AES 加密对字符串进行解码
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)
您的 CryptoJS 代码和 Python 代码存在多个问题。
密钥大小错误
您的密钥 s
仅包含 20 个字节(160 位),不构成 AES 的任何有效密钥大小,即 128 (10)、192 (12) 和 256 位(14 轮) ). CryptoJS 将默默地 运行 11 轮的 160 位密钥的密钥计划,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 = "[=12=]"*16
没有取消填充
CryptoJS 默认使用 PKCS#7 填充,但 PyCrypto 不实现任何填充,仅将数据处理为块大小的倍数。解密后,您需要自己删除 Python:
中的填充value = value[:value[-1]]
(最后一个字节决定了有多少字节是填充字节)。更多关于 here.
其他注意事项:
您真的不应该将 IV 设置为静态值。应该为使用相同密钥的每次加密随机生成 IV。否则,您将失去语义安全性。由于IV不必是秘密的,你可以把它放在密文前面,然后在解密之前把它切掉。