【问题标题】:decryption works using PHP (openssl) and not working using javascript (cryptojs)解密工作使用 PHP (openssl) 而不是使用 javascript (cryptojs)
【发布时间】:2021-03-06 13:33:10
【问题描述】:

使用 php/openssl 进行解密,我可以得到我的纯数据。这是定义的调用:

<?php

function decryptString($data, $key)
{
    return base64_decode(openssl_decrypt(base64_decode($data), "AES-256-CBC", $key, true, "h7oehNIHWGNIHxyN"));
}

function encryptString($data, $key)
{
    return base64_encode(openssl_encrypt(base64_encode($data), "AES-256-CBC", $key, true, "h7oehNIHWGNIHxyN"));
}

echo 'encrypted: ' . encryptString('my sample text', '7f7720b911c2ecbb22637ed7adef41e82d44b6a0') . "\n";

echo 'decrypted: ' . decryptString('rFWejB1Pj6W3Gh1bheFqDZPMO9POKbhGPOP6eAH9BSk=',        '7f7720b911c2ecbb22637ed7adef41e82d44b6a0') . "\n";

我得到这个输出:

encrypted: rFWejB1Pj6W3Gh1bheFqDZPMO9POKbhGPOP6eAH9BSk=
decrypted: my sample text

我尝试使用cryptojs 实现相同的功能,但没有工作,我有时会收到“格式错误的 UTF-8 数据”,有时还会收到其他模棱两可的错误(空字符串/无法读取未定义的属性长度,具体取决于关于我所做的代码更改)。所以这是我迄今为止做的最好的:(我现在有“格式错误的 UTF-8 数据”错误)

function decryptData(encrypted, pass) {
    // encrypted is a base64 encoded string
    let data = let data = Buffer.from(encrypted, "base64").toString();  // I tried this also [ let data = crypto.enc.Base64.parse(encrypted); ]

    let key = crypto.enc.Utf8.parse(pass);
    let decrypted = crypto.AES.decrypt(data, key,
        {
            iv: crypto.enc.Hex.parse('h7oehNIHWGNIHxyN'), // tried passing it as a simple string like this [ iv: 'h7oehNIHWGNIHxyN', ]
            mode: crypto.mode.CBC,
            padding: crypto.pad.NoPadding // I tried also with [ crypto.pad.Pkcs7 ]
        }
    );
let result =  decrypted.toString(crypto.enc.Utf8); //  tried this also [ let result = decrypted.toString(crypto.enc.Base64) ]
}

这是我得到的错误:

/home/vagrant/PhpstormProjects/untitled3/node_modules/crypto-js/core.js:513
                    throw new Error('Malformed UTF-8 data');
                    ^

Error: Malformed UTF-8 data
    at Object.stringify (/home/vagrant/PhpstormProjects/untitled3/node_modules/crypto-js/core.js:513:24)
    at WordArray.init.toString (/home/vagrant/PhpstormProjects/untitled3/node_modules/crypto-js/core.js:268:38)
    at decodeBase64String (/home/vagrant/PhpstormProjects/untitled3/decryptor.js:13:25)
    at Object.<anonymous> (/home/vagrant/PhpstormProjects/untitled3/decryptor.js:19:1)

这可能看起来很明显,但我感到困惑,似乎没有任何效果。你能帮帮我吗?

我尝试遵循但没有成功的问题:

更新 1: 我编辑了这个问题,添加了一个简单的示例消息和完整的 php 加密/解密示例以及我最后一个代码的版本。

【问题讨论】:

  • 我试图关注你,很抱歉我不能。您能否使用代码发布您的实现,以便我看到它有效并且我可以理解它(代码比文字更容易理解。提前谢谢@Topaco :)
  • 当然,我已经发布了用于解密的可能 CryptoJS 实现。

标签: node.js encryption cryptography cryptojs php-openssl


【解决方案1】:

AES 仅针对 16/24/32 字节密钥定义。您正在使用 40 字节的密钥。 PHP 隐式将密钥削减到 32 个字节,CryptoJS 没有,但由于错误 (#293) 处理密钥时没有错误消息,当然结果是错误的。
此外,密文必须作为CipherParams 对象或Base64 编码传递,IV 必须是Utf8 编码,应该使用PKCS7 填充,并且解密的数据是base64 字符串(仍然需要进行Base64 解码)。

以下 CryptoJS 代码解密示例密文:

function decryptData(encrypted, pass) {

    let decryptedWA = CryptoJS.AES.decrypt(
        encrypted,                                              // Pass ciphertext Base64 encoded (or as CipherParams object)
        CryptoJS.enc.Utf8.parse(pass.substring(0, 32)),         // Truncate key to 32 bytes
        {
            iv: CryptoJS.enc.Utf8.parse('h7oehNIHWGNIHxyN'),    // UTF8 encode the IV 
            mode: CryptoJS.mode.CBC,    // default
            padding: CryptoJS.pad.Pkcs7 // default              // Apply PKCS7 padding
        }
    );

    let decryptedB64 =  decryptedWA.toString(CryptoJS.enc.Utf8); 
    let decrypted = CryptoJS.enc.Base64.parse(decryptedB64).toString(CryptoJS.enc.Utf8); // Base64 decode the decrypted data

    return decrypted;
}

var ciphertext = "rFWejB1Pj6W3Gh1bheFqDZPMO9POKbhGPOP6eAH9BSk=";
var key = "7f7720b911c2ecbb22637ed7adef41e82d44b6a0";
console.log(decryptData(ciphertext, key));
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"&gt;&lt;/script&gt;

请注意,静态 IV 是不安全的(但也许您只是将静态 IV 用于测试目的)。

【讨论】:

  • 像魅力一样工作,谢谢!我现在看到了棘手的问题(将密钥减少到 32 个字节/iv Utf8 配对和所需的 Pkcs7 填充)。关于静态 iv,我无法控制加密过程(外部提供者),但感谢您的注意!
猜你喜欢
  • 1970-01-01
  • 2021-12-20
  • 1970-01-01
  • 1970-01-01
  • 2017-05-04
  • 2014-12-24
  • 1970-01-01
  • 1970-01-01
  • 2020-09-24
相关资源
最近更新 更多