使用 CryptoJS 解密 openssl_seal 中的密文

Иго*_*орь 2 javascript php openssl cryptography cryptojs

我需要使用公钥使用 PHP 来编码消息,并使用私钥使用 javascript 来解码该消息。

这是测试代码:

<?php
$message = 'sevenflash';

$public_key = openssl_get_publickey(file_get_contents('pubkey.pem'));

$encrypted = $e = NULL;
openssl_seal($message, $encrypted, $e, array($public_key));

$sealed_data = base64_encode($encrypted);
$envelope = base64_encode($e[0]);

$unsealed = null;
openssl_open(base64_decode($sealed_data), $unsealed, base64_decode($envelope), file_get_contents('privatekey.pem'));
echo $unsealed; // This is sevenflash

$embed = "<script>var encrypted = '$sealed_data'; var envelope = '$envelope'; </script>";
?>
<html>
<head>
    <script type="text/javascript" src="rc4.js"></script>
    <script type="text/javascript" src="enc-base64.js"></script>
    <script type="text/javascript" src="jsencrypt/bin/jsencrypt.js"></script>
    <?php echo $embed; ?>
    <script>
        var private_key = `...`;

        var crypt = new JSEncrypt();
        crypt.setPrivateKey(private_key);
        var theKey = crypt.decrypt(envelope);

        var decrypted = CryptoJS.RC4.decrypt(encrypted, theKey);
        console.log(decrypted.toString()); // This must be sevenflash, but this is 696a2b0440220d69e8c3
    </script>
</head>
<body>

</body>
</html>
Run Code Online (Sandbox Code Playgroud)

但这行不通。为什么?

Art*_* B. 5

CryptoJS 解密需要一个CipherParams对象来代替密文和一个WordArray来代替密钥。如果您将密钥作为字符串传递,那么它将假定它是密码,并尝试使用 MD5 和不存在的盐从中派生密钥。

\n\n

尝试解析所有内容:

\n\n
var decrypted = CryptoJS.RC4.decrypt({\n    ciphertext: CryptoJS.enc.Base64.parse(encrypted)\n}, CryptoJS.enc.Latin1.parse(theKey));\n
Run Code Online (Sandbox Code Playgroud)\n\n

JSEncrypt 从函数返回一个“纯字符串” crypt.decrypt(),这意味着必须使用 Latin1 或 UTF-8 编码对其进行解析。
\n但是我无法让它与 JSEncrypt 一起工作,所以我使用了forge来代替:

\n\n
var privateKey = forge.pki.privateKeyFromPem(private_key);\nvar theKey = privateKey.decrypt(forge.util.decode64(envelope), \'RSAES-PKCS1-V1_5\');\n
Run Code Online (Sandbox Code Playgroud)\n\n

CrypoJS\'.toString()默认返回十六进制编码版本。您可以覆盖它以获取文本数据:

\n\n
console.log(decrypted.toString(CryptoJS.enc.Utf8));\n
Run Code Online (Sandbox Code Playgroud)\n\n

\r\n
\r\n
var decrypted = CryptoJS.RC4.decrypt({\n    ciphertext: CryptoJS.enc.Base64.parse(encrypted)\n}, CryptoJS.enc.Latin1.parse(theKey));\n
Run Code Online (Sandbox Code Playgroud)\r\n
var privateKey = forge.pki.privateKeyFromPem(private_key);\nvar theKey = privateKey.decrypt(forge.util.decode64(envelope), \'RSAES-PKCS1-V1_5\');\n
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n