【问题标题】:Is AES the same in libraries PyCrypto & Node.JS CryptoPyCrypto 和 Node.JS Crypto 库中的 AES 是否相同
【发布时间】:2011-03-17 21:51:15
【问题描述】:

我开始怀疑 AES 的实现是否因库而异..

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

基本上使用 PyCrypto..
我使用带有随机生成 IV 的 AES-128-CBC。 (在 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')

吐出一堆垃圾......(将“二进制”更改为 hex/utf8 无济于事)

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

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

我是否对 Node.js 的标准库期望过高?

【问题讨论】:

  • 有人知道可以处理此任务的其他模块吗??

标签: node.js aes encryption pycrypto


【解决方案1】:

文档没有提到这一点,但您传递给 crypto.createDecipheraeskey 不是 密钥,而是一个密码,由 OpenSSL 的 EVP_BytesToKey 函数处理。

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

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    【解决方案3】:

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

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

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

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

    【讨论】:

    • 为了清楚起见..请阅读这个..groups.google.com/group/nodejs/browse_thread/thread/…Cheers
    • 我刚刚在 Node 下创建了一个用于加密/解密的新库,因为加密问题也一直困扰着我:github.com/TrevorBurnham/cipherpipe 它只是 openssl 的一个薄包装。试试看,让我知道你的想法。
    • npm 错误! 404 看起来 'cipherpip' 不在 npm 注册表中。 npm 错误! 404 你应该让作者发布它。 :( ...我很想试试这个
    • 哎呀,忘了npm publish。对于那个很抱歉。再试一次。
    • /usr/local/lib/node/.npm/cipherpipe/0.1.0/package/lib/cipherpipe.js:6 return '"' + str.replace(/\\/g, '\\\\').replace(/"/g, '\\"') + '"'; ^ TypeError: Cannot call method 'replace' of undefined ...我不能使用您的 frombase64 方法...在我的示例中使用 base64,并尝试解码 Aes .. 导致..“未定义”被返回 :(
    【解决方案4】:

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

    【讨论】:

    • 在节点 0.4.2 中,没有提到使用 IV 的 ???如果你看一下 CBC 设计,你就会明白,在它前面加上零,因为 IV 将正确地启动链..在开头留下一个垃圾块..这类似于 pgp 的功能..跨度>
    • 嗯,我确实在代码中找到了 crypto.createDecipheriv(cipher, key, iv) .. 但是它仍然无法正常工作:(
    【解决方案5】:

    确保在 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 解码为十六进制

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多