如何用JSEncrypt对PHP中的数据进行解密

时间:2022-11-03 18:34:20

I'm trying to secure communication between a JS front-end and a PHP backend by using symmetric and asymmetric encryption. I'm creating a symmetric key on the client and encrypting it with the server's public key with JSEncrypt and sending it to the server for future use. However, I'm getting stuck when I get the data on the server side. openssl_open requires an envelope to decrypt the symmetric key and I'm not even positive what data is supposed to be in the envelope. I was under the impression that the envelope is the symmetric key that was encrypted with the public key, but using that has not worked. I've also tried different combinations of decoding as I've read that JSEncrypt encodes the message in base 64 and the key in hex, but those attempts are fruitless as well.

我试图通过使用对称和非对称加密来保护JS前端和PHP后端之间的通信。我正在客户机上创建一个对称密钥,并使用服务器的公钥对其进行加密,并将其发送到服务器以备将来使用。但是,当我在服务器端获得数据时,我就会陷入困境。openssl_open需要一个信封来解密对称密钥,我甚至不能确定信封中应该包含哪些数据。我的印象是,信封是用公钥加密的对称密钥,但使用公钥是行不通的。我也尝试过不同的解码组合,因为我读过JSEncrypt对base 64和key进行编码,但是这些尝试都是徒劳的。

JS encryption code:

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 decryption code:

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;

The code above outputs nothing because the openssl_open call fails (returns false). When I base 64 decode the $encryptedKey variable, I get:

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

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

but the symmetric key changes every time, so the output changes every time as well. Like I said, I've tried different encoding combinations, but they all return similar nonsense. As the JS code shows, I've encrypted the message "test".

但是对称键每次都在变化,所以输出每次都在变化。就像我说的,我尝试过不同的编码组合,但它们都返回类似的无意义。如JS代码所示,我对消息“test”进行了加密。

I've never implemented encryption before, so I might be way off the mark here, but after staring at this code for days, any insight would be appreciated.

我以前从来没有实现过加密,所以我可能在这里偏离了目标,但是在看了这段代码几天之后,任何见解都会受到赞赏。

Edit: I'm having problems decrypting with my private key in PHP, not with the symmetric key

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

1 个解决方案

#1


1  

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:

搞懂了! ! !因此,我发现PHP有一个用于解密的函数,而不需要一个名为openssl_private_decrypt的信封,该信封使用私钥解密消息。通过使用这个函数并使用base 64解码加密密钥,我能够解密服务器端上的对称密钥,并且现在有望能够对称地解密消息。对于那些感兴趣的人,我在服务器端的代码是:

$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!

在客户端,我的代码和上面一样。希望这可以帮助别人!

#1


1  

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:

搞懂了! ! !因此,我发现PHP有一个用于解密的函数,而不需要一个名为openssl_private_decrypt的信封,该信封使用私钥解密消息。通过使用这个函数并使用base 64解码加密密钥,我能够解密服务器端上的对称密钥,并且现在有望能够对称地解密消息。对于那些感兴趣的人,我在服务器端的代码是:

$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!

在客户端,我的代码和上面一样。希望这可以帮助别人!