PyCrypto 和 PyCrypto 库中的 AES 是否相同? Node.JS 加密

发布于 2024-10-23 18:55:05 字数 605 浏览 6 评论 0原文

我开始怀疑 AES 的实现是否在各个库中有所不同。

目前我有一个用 PyCrypto 加密的明文。
我正在尝试使用 Node.js 的加密库解密密文..

基本上使用 PyCrypto ..
我使用 AES-128-CBC 和随机生成的 IV。 (在 PyCrypto 中完美解密)

但是..
在 Node.js 上,我这样做

var buf = new Buffer(ciphertext)
var decipher = crypto.createDecipher('aes-128-cbc',aeskey)
buf = decipher.update(buf,'binary', 'binary')
buf += decipher.final('binary')

会吐出一堆垃圾......(将“二进制”更改为十六进制/utf8 没有帮助)

因为我正在使用 CBC(密码块链接)......
我将 IV 添加到密文的开头(16 个块)。 在 PyCrypto 中,这完美地工作,类似于 PGP、CFB 使用的规范。

有谁知道这不起作用的原因是什么???

我是否对 Node.js 的标准库期待太多?

I am beginnging to wonder if the implementation of AES is different across libraries..

Currently i have a plaintext encrypted with PyCrypto.
Im trying to decrypt the ciphertext with Node.js's Crypto Library..

Basically with PyCrypto..
im using AES-128-CBC with a random generated IV. (which decrypts perfectly in PyCrypto)

However..
On Node.js im doing this

var buf = new Buffer(ciphertext)
var decipher = crypto.createDecipher('aes-128-cbc',aeskey)
buf = decipher.update(buf,'binary', 'binary')
buf += decipher.final('binary')

Which spits out a bunch of Garbage.... ( changing 'binary' to hex/utf8 doesnt help)

As i am using CBC (Cipher Block Chaining)...
i am prepending the IV to the beginning of the ciphertext (16 blocks)..
In PyCrypto this works perfectly, similarly to the specification of PGP, CFB usage..

Does anyone know for what reason this is not working???

Am i expecting too much of Node.js's standard libraries?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

茶花眉 2024-10-30 18:55:06

文档没有提到这一点,但是您传递给 crypto.createDecipheraeskey 不是密钥,而是一个密码,由 OpenSSL 处理< a href="http://www.openssl.org/docs/crypto/EVP_BytesToKey.html" rel="nofollow">EVP_BytesToKey 函数。

要传递实际的原始密钥数据,应该使用(目前未记录)crypto.createDecipheriv(cipher, key, iv) 函数。这也适用于 ECB 模式,即使 ECB 中没有 IV。

如果失败,我认为调试的第一步是尝试使用 AES KAT查看解密代码是否正确。

我在这里遇到了类似的问题: https://github.com/joyent/node/issues /1318

Documentation does not mention this, but aeskey you're passing to crypto.createDecipher is not the key, but a password, handled to OpenSSL's EVP_BytesToKey function.

To pass the actual raw key data one should use (presently undocumented) crypto.createDecipheriv(cipher, key, iv) function. This applies to ECB mode too, even though there's no IV in ECB.

If this fails, I think, the first step in debugging would be to try with AES KATs to see whenever the decryption code is correct.

I've tripped on a similar issue here: https://github.com/joyent/node/issues/1318

も让我眼熟你 2024-10-30 18:55:06

AES 是一个 Rijndael 标准。不应该有什么不同。您应该查看隐藏的数据类型和默认设置。两者之间必须设置不同的东西。密钥大小可能会有所不同,因为我认为 128 位“hello”用零填充,较小的密钥将以“hello”开头,但填充较小,因此有所不同。

AES is a rijndael standard. It shouldn't be different. You should look into data types and default settings that are hidden. Something must be set different between the two. The key sizes might be different as 128 bit "hello" is padded with zeros I think and a smaller key would start with "hello" but have a smaller padding, therefore different.

网白 2024-10-30 18:55:06

对您问题的简短回答是:是的,PyCrypto 和 Node.js 的 crypto 模块中的 AES 是相同的。 Node 的 crypto 只是系统上 openssl 的包装,PyCrypto 可以与 OpenSSL 互操作(请参阅 http://lists.dlitz.net/pipermail/pycrypto/2010q4/000301.html)。

话虽如此,Node crypto 模块中肯定存在错误(尽管我自己只遇到过 base64 编码的问题)。因此,无论是否是错误,您遇到的问题几乎肯定发生在数据编码/解码阶段。

您的密文是什么样的?它是一个十六进制字符串吗?如果是这样,那么你需要这样做

buf = decipher.update(buf, 'hex', 'binary')

The short answer to your question is: Yes, AES is the same in PyCrypto and Node.js' crypto module. Node's crypto is just a wrapper around openssl on your system, and PyCrypto is interoperable with OpenSSL (see http://lists.dlitz.net/pipermail/pycrypto/2010q4/000301.html).

Having said that, there are definitely bugs in the Node crypto module (though I've only experienced problems with base64 encoding, myself). So whether it's a bug or not, the problems you're experiencing are almost certainly happening in the data encoding/decoding stages.

What does your ciphertext look like? Is it a hexadecimal string? If so, then you need to do

buf = decipher.update(buf, 'hex', 'binary')
假情假意假温柔 2024-10-30 18:55:06

这不是 IV 在 Node 中的工作方式,你必须使用 crypto.createDecipheriv(cipher, key, iv) 来代替,否则你会得到一个默认的内置的。即使在 PyCrypto 中,您也应该使用 AES.new 的第三个参数作为 IV,而不是将其填充到字节流中。

That's not how IV works in Node, you have to use crypto.createDecipheriv(cipher, key, iv) instead, otherwise you get a default baked-in one. Even in PyCrypto you should be using the third argument to AES.new as the IV, not stuffing it into the bytestream.

生死何惧 2024-10-30 18:55:06

确保在 pycrypto 和 node.js 中使用相同的密钥和 IV!不仅如此,还要确保两端具有相同的编码:

cipher = AES.new(key.decode('hex'), AES.MODE_CBC, iv.decode('hex'))
text = json.dumps(payload)  
pad = lambda s: s + (16 - len(s) % 16) * '\x07'     
encryptedText = base64.b64encode(cipher.encrypt(pad(text)))

然后在 node.js 中(抱歉,现在无法轻松访问该代码),还要确保将密钥和 iv 解码为十六进制

Make sure you use the same key and IV in both pycrypto and node.js!! Not only that, but make sure you have the same encoding in both ends:

cipher = AES.new(key.decode('hex'), AES.MODE_CBC, iv.decode('hex'))
text = json.dumps(payload)  
pad = lambda s: s + (16 - len(s) % 16) * '\x07'     
encryptedText = base64.b64encode(cipher.encrypt(pad(text)))

Then in node.js (sorry, no easy access to that code now), also make sure you decode your key and iv to hex

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文