【问题标题】:Encrypt with AES using phpseclib and decrypt with CryptoJS使用 phpseclib 使用 AES 加密并使用 CryptoJS 解密
【发布时间】:2016-03-02 10:41:53
【问题描述】:

我正在尝试在 CBC 模式下使用 phpseclib AES 加密字符串(库的默认设置):

$cipher = new Crypt_AES();
$cipher->setKey('abcdefghijklmnop');
$cipher->setIV(crypt_random_string($cipher->getBlockLength() >> 3));
$cipher->encrypt("hello world")

然后,我需要使用 CryptoJS 或类似方法在 nodejs 上解密。我尝试了不同的库,但到目前为止还没有运气。我猜这个问题与每个库的编码输出不同有关。

有没有人有一个如何实现这种互操作性场景的工作示例?

可以使用其他库,例如 Crypto。 示例 Base64 输出为 MF9lCR4DaW1R0adIe03VEw==

所以思路是解密如下:

var helloWorld = CryptoJS.AES.decrypt("MF9lCR4DaW1R0adIe03VEw==", key).toString();

【问题讨论】:

  • 当有一个内置且速度更快的第三方加密库时,为什么还要在节点中使用第三方加密库?
  • 你能给出加密输出的例子吗(例如 hex 或 base64)?
  • @mscdex 刚刚根据您的要求用一些示例更新了问题。顺便说一句,节点的加密库也是一个选项..
  • 解密不需要IV吗?

标签: node.js encryption aes phpseclib cryptojs


【解决方案1】:

在解密过程中您需要之前生成的 IV。它不一定是秘密的,但它必须是不可预测的(在你的情况下就是这样)。您可以将其与密文一起发送。一种常见的方法是将其添加到密文中,并在解密时将其切掉。

CryptoJS 支持两种类型的加密。如果您将密钥作为字符串传递,它将使用 OpenSSL 的密钥派生函数来派生带有盐的新密钥。您不希望这样,因为您使用的是显式密钥。为此,您需要将密钥作为 WordArray(CryptoJS 的本机二进制数据结构)传递。此外,密文应该是 OpenSSL 格式的字符串或 CipherParams 对象:

var message = CryptoJS.AES.decrypt({
    ciphertext: CryptoJS.enc.Base64.parse("MF9lCR4DaW1R0adIe03VEw==")
}, CryptoJS.enc.Utf8.parse('abcdefghijklmnop'), {
    iv: iv // retrieve the IV somehow
}).toString(CryptoJS.enc.Utf8);

【讨论】:

  • 我以为 IV 已经附加到加密数据(密文)中,并且会在节点上无缝解析。所以我没有尝试手动设置它。感谢您的回复!
  • 您可以通过查看密文的长度来检查这一点。 Base64 的膨胀率为 4/3。这意味着实际密文长度len(b64)*3/4-paddingChars,在您的情况下为24*3/4-2 = 18 - 2 = 16。 16 是 AES 的块大小,由于 CBC 是一种非流模式,它必须至少产生一个块。所以IV没有地方存在。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-24
  • 1970-01-01
  • 2016-10-05
  • 2014-08-17
  • 2017-11-01
  • 2017-01-11
  • 1970-01-01
相关资源
最近更新 更多