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

python(pycrypto)和nodejs(crypto)之间的加密(aes-128-cbc)不匹配

濮献
2023-03-14

我已经得到了这段python代码,我需要将其翻译成nodejs。python代码使用来自加密的pycrypto。在nodejs方面,我使用的是本机加密模块。加密字符串之间似乎不匹配。

from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex
import json

raw_key = [0x58, 0x86, 0x17, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x28, 0xa4, 0x5a]
key = str(bytearray(raw_key))

raw_iv =  [0x34, 0x2e, 0x17, 0x99, 0x6d, 0x19, 0x3d, 0x28, 0xdd, 0xb3, 0xa2, 0x69, 0x5a, 0x2e, 0x6f, 0x1b]
iv = str(bytearray(raw_iv))

text = json.dumps({ "a": 1, "b": 2 })

cryptor = AES.new(key, AES.MODE_CBC, iv)
length = 16
count = len(text)
add = length - (count % length)
text = text + ('\0' * add)
encrypted = cryptor.encrypt(text);
print b2a_hex(encrypted)

上面的python代码输出

5c72b1a394654b6dab9ea8fdd90fe56b92141d74cb32ac65ede4d3154801bb57

而下面的nodejs代码

const crypto = require('crypto');

const KEY = Buffer.from([0x58, 0x86, 0x17, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x28, 0xa4, 0x5a]);
const IV = Buffer.from([0x34, 0x2e, 0x17, 0x99, 0x6d, 0x19, 0x3d, 0x28, 0xdd, 0xb3, 0xa2, 0x69, 0x5a, 0x2e, 0x6f, 0x1b]);

const text = JSON.stringify({ a: 1, b: 2 });

const cipher = crypto.createCipheriv('aes-128-cbc', KEY, IV);
cipher.setAutoPadding(true);
const encrypted = Buffer.concat([cipher.update(text, 'utf-8'), cipher.final()]);
console.log(encrypted.toString('hex'));

输出

d6a0dbc6df2a1038036e4db985f9ca10

为什么他们不匹配?我做错什么了吗?

共有1个答案

彭弘伟
2023-03-14

这里有两个问题:

>

JSON的格式在节点和python之间略有不同。javascript的JSON. stringify()删除了所有不必要的空白,而python留下了一些空白(例如数组/对象中的元素之间)。对此最简单的解决方案可能是更改python代码以指定显式的分隔符选项:json.dumps({"a": 1,"b": 2},分隔符=(',', ':')),因为javascript的JSON. stringify()在以这种方式更改格式时并不灵活。

下面的节点代码显示,通过匹配JSON输出并使用适当的填充,您将获得与python相同的十六进制输出:

const crypto = require('crypto');

const KEY = Buffer.from([0x58, 0x86, 0x17, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x28, 0xa4, 0x5a]);
const IV = Buffer.from([0x34, 0x2e, 0x17, 0x99, 0x6d, 0x19, 0x3d, 0x28, 0xdd, 0xb3, 0xa2, 0x69, 0x5a, 0x2e, 0x6f, 0x1b]);

var text = '{"a": 1, "b": 2}';

const cipher = crypto.createCipheriv('aes-128-cbc', KEY, IV);
cipher.setAutoPadding(false);

var length = 16;
var count = Buffer.byteLength(text);
var add = length - (count % length);
if (add > 0)
  text += '\0'.repeat(add);

const encrypted = Buffer.concat([cipher.update(text, 'utf-8'), cipher.final()]);
console.log(encrypted.toString('hex'));
 类似资料:
  • 我只需要通过代码加密AES CBC 128位模式的字符串。我使用openssl库完成了这项工作,但无法获得正确的输出。 到目前为止,我已经完成了。 我的十六进制输出是:B0 15 751B50 80 D4 FF 81 68 146BB71B95 99 37 38 但正确的输出是:< code > 73 5C 04 F9 57 18 43 7C EE 68 27 59 2B 41 A8 DA (通过

  • 我正在尝试在python中实现此代码(我是python新手),它给我以下错误: attribute error:“str”对象没有属性“decode” 如果我们删除 只是为了避免这样的错误: 但它给我以下错误: ValueError:IV必须为16字节长 因为算法需要,我必须删除 有没有人知道我该怎么做才能使这段代码工作?

  • 我希望有一个用C编写的程序,可以在没有openssl这样的大型库的帮助下,用AES-CBC对字符串进行编码/解码。 目标: 使用密码短语对字符串进行编码/解码: 因此,应用程序需要接受3个输入参数。。。 输入字符串(待编码)/或已编码字符串(待解码) 用于编码/解码字符串的密码 编码或解码指示器 我对C语言不熟悉(我可以用C#编码)。 我已经找到了https://github.com/kokke/

  • 我用java编写了这段代码,以便解密密文。我有钥匙。对我来说,一切都是正确的,但我有我要解释的问题。 这是我的代码: 我收到以下错误: 出了什么问题?我知道这个问题在某种程度上与衬垫有关,但我不知道确切的解决方案。我只有一个密文IV和密钥。

  • 我只想用这3种模式测试openSSL中的AES:128192和256密钥长度,但我解密的文本与我的输入不同,我不知道为什么。此外,当我传递一个巨大的输入长度(比如1024字节)时,我的程序显示。。。我的意见总是一样的,但这并不重要,至少现在是这样。代码如下: 编辑: 当我将输出大小更改为而不是时,我得到了结果: 那么,是否有可能存在Outpus大小和IV大小的问题?它们应该有什么尺寸(AES-CB

  • 我最近在Java中使用了AES CBC 128算法来加密数据。现在我需要用PHP重建算法,但我不知道如何重建,因为互联网上的PHP算法返回不同的结果。也许你能帮我。 这是要加密的Java代码: 这是我的php代码: 当我从java加密加密数据时,此结果无法在Php解密上解密。 你们能帮我构建一个PHP脚本吗?它可以返回与java加密相同的结果?