简体   繁体   English

将AES解密从CryptoJS移植到PyCrypto

[英]Porting AES decryption from CryptoJS to PyCrypto

Here is a JavaScript part which decodes a string with AES encryption 这是一个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)

I am trying to code a similar decoding function in python with importing AES. 我正在尝试通过导入AES在python中编写类似的解码功能。

Could anyone help me with this one. 谁能帮我这个忙。 I can't figure out all equivalent code for js to python. 我无法弄清楚js到python的所有等效代码。

I looked up this page Python AES Decryption Routine (Code Help) and 我在此页面上查找了Python AES解密例程(代码帮助)

AES - Encryption with Crypto (node-js) / decryption with Pycrypto (python) AES-使用加密(node-js)进行加密/使用Pycrypto(python)进行解密

Not sure if they have the code similar to the js I have here 不知道他们是否有与我在这里的js类似的代码

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

This in python what it means 这在python中是什么意思

I have tried something like this from another source 我已经从其他来源尝试过类似的方法

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)

There are multiple problems with your CryptoJS code and Python code. 您的CryptoJS代码和Python代码存在多个问题。

Wrong key size 密钥大小错误

Your key s contains only 20 bytes (160 bit) which doesn't constitute any of the valid key sizes for AES which are 128 (10), 192 (12) and 256 bit (14 rounds). 您的键s只包含20个字节(160位),这并不构成任何有效密钥大小为AES其是128(10)的,192(12)和256位(14轮)。 CryptoJS will silently run the key schedule for a 160 bit key with 11 rounds which PyCrypto doesn't support (see AES.c ). CryptoJS将通过PyCrypto不支持的 11个回合以静默方式为160位密钥运行密钥调度(请参阅AES.c )。

You can reduce the key to 128 bit like this in CryptoJS: 您可以在CryptoJS中将密钥减少到128位:

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

or in Python: 或在Python中:

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

Wrong character encoding 字符编码错误

You forgot to decode the key from a Base64 string in Python and you forgot to decode the IV from hex. 您忘记了在Python中从Base64字符串解码密钥,而忘记了从十六进制解码IV。 The character '0' and the byte 0x00 are entirely different. 字符'0'和字节0x00完全不同。 There's an easier way to define an all zero IV: 有一种更简单的方法来定义全零IV:

iv = "\0"*16

No unpadding 禁止松动

CryptoJS uses PKCS#7 padding by default, but PyCrypto doesn't implement any padding and only handles data as a multiple of the block size. 默认情况下,CryptoJS使用PKCS#7填充,但是PyCrypto不实现任何填充,仅将数据处理为块大小的倍数。 After you decrypt something, you need to remove the padding yourself in Python: 解密某些内容后,您需要在Python中自行删除填充:

value = value[:value[-1]]

(the last byte determines how many bytes are padding bytes). (最后一个字节确定填充字节为多少个字节)。 More on that here . 这里更多。


Other considerations: 其他注意事项:

You really shouldn't be setting the IV to a static value. 您实际上不应该将IV设置为静态值。 The IV should be randomly generated for every encryption using the same key. 应该为使用相同密钥的每次加密随机生成IV。 Otherwise, you will lose semantic security. 否则,您将失去语义安全性。 Since the IV doesn't have to be secret, you can put it in front of the ciphertext and slice it off before decryption. 由于IV不必是秘密的,因此可以将其放在密文前面,并在解密之前将其切成薄片。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM