当前位置: 首页 > 知识库问答 >
问题:

将AES解密从CryptoJS移植到PyCrypto

彭高畅
2023-03-14

这里是一个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)

我试图用python编写一个类似的解码函数,并导入AES。

谁能帮我做这个吗。我无法找出js到python的所有等效代码。

我查了这个页面Python AES解密例程(代码帮助)和

AES-加密与加密(node-js)/解密与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个答案

宗政浩慨
2023-03-14

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

您的密钥s仅包含20个字节(160位),这不构成AES的任何有效密钥大小,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字符串解码密钥,而忘记了从hex解码IV。字符'0'和字节0x00完全不同。有一种更简单的方法来定义全零IV:

iv = "\0"*16

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

value = value[:value[-1]]

(最后一个字节确定填充字节的字节数)。这里有更多。

其他考虑:

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

 类似资料:
  • null Edit2:为了一致性和正确性,将填充重命名为iVector。

  • 我之所以问这个问题,是因为两天来我读了很多关于crypto AES加密的帖子,就在我以为我得到了它的时候,我意识到我根本没有得到它。 这个帖子是最接近我的问题,我有完全相同的问题,但它没有得到回答: CryptoJS AES加密与JAVA AES解密值不匹配 我得到的是已经加密的字符串(我得到的代码只是为了看看他们是怎么做的),所以修改加密方式不是一个选项。这就是为什么所有类似的问题对我来说都不是

  • 我需要解密用AES加密的传入请求,我尝试使用共享示例但无法找到正确的参数集 加密:AES/CBC/PKCS5添加AES/CBC/PKCS5 初始化向量:长度为16的空字节数组 测试密钥:1234567890123456 纯文本:abcdefghigklmnopqrstuvwxyz0123456789 加密:8Z3dZzqn05FmiuBLowExK0CAbs4TY2GorC2dDPVlsn/tP

  • 注意:这只是为个人使用和学习,我不是试图滚动我自己的加密为公众使用。 我需要AES256加密一个字符串,但是我当前的尝试在十六进制解码时最终得到了一个类似server side的字符串。当十六进制解码时,它应该是一个有效的utf8 base64字符串,然后可以将其解码为原始字符串。这与这里提供的解决方案类似,但是salt并不是实际问题(尽管答案被接受),并且我无法在使用之前通过十六进制解码iv来抑

  • 客户端: 服务器端:

  • 我使用JavaAPI生成128bit密钥。下面是我使用的算法: 我可以通过这些方法轻松地使用secretKey加密和解密消息。由于Java默认使用128bit AES加密,因此它使用SHA1生成原始密钥的哈希,并将哈希的前16字节用作AES中的密钥。然后以十六进制格式转储IV和密文。 但是,它返回一个空字符串。