如何使用由 travist/jsencrypt 加密的 phpseclib class Crypt_RSA 解密数据

How to decrypt data using phpseclib class Crypt_RSA that was encrypted by travist/jsencrypt

我使用 linux ubuntu 服务器和 nginx,mysql,php7.3

  1. 我正在尝试使用 public rsa 密钥加密消息,该密钥是在服务器端使用 phpseclib (http://phpseclib.sourceforge.net/)
  2. 生成的
<?php
//session_start();
$rsa = new Crypt_RSA(); 
extract($rsa->createKey()); 
$rsa->loadKey($privatekey); 
$_SESSION['pr']=(empty($_SESSION['pr'])) ? $rsa : $_SESSION['pr'];
$rsa->loadKey($publickey);
$_SESSION['pu']=(empty($_SESSION['pu'])) ? $rsa : $_SESSION['pu'];
?>
  1. 然后我尝试使用生成的密钥通过 JSEncrypt 库 (https://github.com/travist/jsencrypt) 加密和解密消息,目前它有效
<br /><input type="button" value="Show Encrypted" onclick="alert(crypted);"/>&nbsp;<input type="button" value="Show Decrypted" onclick="alert(decrypt);"/><br />
<script type="text/javascript">
var crypt = new JSEncrypt();
var public_key = '<?php echo der2pem($_SESSION["pu"], "RSA PUBLIC KEY";?>';
crypt.setPublicKey(public_key);
var input='i\'ve got a power';
var crypted=crypt.encrypt(input);
var decrypt=crypt.decrypt(crypted);
alert(crypted);
alert(decrypt);
</script>
  1. 最后我尝试使用 phpseclib rsa 实现用私钥解密 JSEencrypted 消息。期望获得原始的未加密消息,但我得到的只是通知:第 2507 行 enc/RSA.php 中的解密错误 请帮帮我,我试过放入 b64 解码字符串、十六进制字符串,试图删除斜杠或 + 符号,但没有任何帮助。给我指出正确的方向,请让我像个婊子一样被卡住。提前致谢!
<?php
// here i put the crypted var showed in alert
$var=base64_decode('##put your variable here');

$rsa->loadKey($_SESSION['pr']);
$dec=$rsa->decrypt($var);
echo '<br />'.$dec;
?>

嗨,纽伯特!感谢您的回答,您确实帮助我弄清楚了我遇到的确切问题:当我使用 crypt.encrypt 函数而不先设置密钥时,它会自己创建密钥对,然后自行设置,所以我会无法使用保存在我的 php 会话中的密钥解密消息。但下一个问题是 crypt.setKey 函数需要的 pem rsa 格式。所以现在我想问你知道如何将 b64 编码的 $rsa 转换为 pem 格式,我试图在密钥的两边添加相应的行但它没有帮助。我是否应该将它分解为 64 字节的行,每行末尾都带有“\n”?已经找到这样的函数here

在 phpseclib 中执行实际解密操作之前尝试添加:

$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);

phpseclib 默认使用更安全但不太常见的 OAEP 填充。

正如 neubert 所说,我必须添加这一行 $rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);在执行加密操作之前 然后使用 here 中的函数将 RSA 密钥从 DER 格式转换为 PEM 格式,然后在 crypt.setPublicKey():

中进行设置
<?php
function der2pem($der_data, $type='CERTIFICATE') {
   $pem = chunk_split(base64_encode($der_data), 64, "\n");
   $pem = "-----BEGIN ".$type."-----\n".$pem."-----END ".$type."-----\n";
   return $pem;
}

?>

谢谢!!!

我遇到了同样的问题,那是因为编码问题,所以请确保 php 端

$enc =   base64_decode ($request->encrypted);