2

我正在尝试通过使用对称和非对称加密来保护 JS 前端和 PHP 后端之间的通信。我正在客户端上创建一个对称密钥,并使用 JSEncrypt 使用服务器的公钥对其进行加密,并将其发送到服务器以供将来使用。但是,当我在服务器端获取数据时,我被卡住了。openssl_open 需要一个信封来解密对称密钥,我什至不肯定信封中应该包含什么数据。我的印象是信封是用公钥加密的对称密钥,但使用它并没有奏效。我也尝试过不同的解码组合,因为我读到 JSEncrypt 将消息编码为 base 64,密钥编码为十六进制,但这些尝试也没有结果。

JS加密代码:

let pub = "-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----";

//I have a function that just creates a random string of characters
let key = generateKey(32);
let aesData = CryptoJS.AES.encrypt( "test", key );
let symKey = aesData.key + ":::" + aesData.iv;
let msg = aesData.toString();

let rsa = new JSEncrypt();
rsa.setPublicKey( pub );
let cryptKey = rsa.encrypt( symKey );

//I'm passing the data through a hidden form field
$("#key").val(cryptKey + ":::" + msg);

PHP解密代码:

$key = openssl_get_privatekey( file_get_contents( $_SERVER["PRIV_KEY"]) );
$encryptedKey = explode( ":::", $msg )[0];
$realMsg = base64_decode(explode( ":::", $msg )[1]);

openssl_open($realMsg, $decrypted, $encryptedKey, $key);
return $decrypted;

上面的代码没有输出任何内容,因为 openssl_open 调用失败(返回 false)。当我对 $encryptedKey 变量进行 base 64 解码时,我得到:

�vEi���pΕ��d_���@����욲JE��

但是对称密钥每次都会改变,所以输出也每次都会改变。就像我说的,我尝试了不同的编码组合,但它们都返回类似的废话。正如 JS 代码所示,我已经加密了消息“test”。

我以前从未实施过加密,所以我在这里可能有点离题,但是在盯着这段代码好几天之后,任何见解都会受到赞赏。

编辑:我在使用 PHP 中的私钥解密时遇到问题,而不是使用对称密钥

4

1 回答 1

2

Figured it out!!! So, I found out that PHP has a function to decrypt without needing an envelope called openssl_private_decrypt that uses a private key to decrypt a message. By using that function and base 64 decoding the encrypted key, I am able to decrypt the symmetric key on the server side and will hopefully be able to decrypt the message symmetrically now. For those interested, my code on the server side is:

$key = openssl_get_privatekey( file_get_contents( $_SERVER['PRIV_KEY'] ) );
$encryptedKey = base64_decode(explode( ":::", $msg )[0]);

if( openssl_private_decrypt($encryptedKey, $decrypted, $key) )
{
    return $decrypted;
}
return $encryptedKey;

And on the client side, my code is the same as it was above. Hope this helps someone!

于 2018-02-25T19:16:32.773 回答