RSA Encrypt in PHP to decrypt in .NET

断了今生、忘了曾经 提交于 2019-11-29 04:05:18
user260294

Security Warning: Use OAEP, not PKCS#1.

If you want to use a solution that doesn't require the openssl extension, try phpseclib's Crypt_RSA. Examples follow:

Decryption with PKCS#1 padding:

openssl rsautl -inkey privatekey.txt -encrypt -in plaintext.txt -out ciphertext.txt

<?php
include('Crypt/RSA.php');

$rsa = new Crypt_RSA();
$rsa->loadKey(file_get_contents('privatekey.txt'));
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
echo $rsa->decrypt(file_get_contents('ciphertext.txt'));
?>

Encryption with PKCS#1 padding:

<?php
include('Crypt/RSA.php');

$rsa = new Crypt_RSA();
$rsa->loadKey(file_get_contents('privatekey.txt'));
$rsa->loadKey($rsa->getPublicKey());
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
echo $rsa->encrypt('1234567890');
?>

openssl rsautl -inkey privatekey.txt -decrypt -in ciphertext.txt -out plaintext.txt

Decryption with OAEP padding:

openssl rsautl -inkey privatekey.txt -encrypt -oaep -in plaintext.txt -out ciphertext.txt

<?php
include('Crypt/RSA.php');

$rsa = new Crypt_RSA();
$rsa->loadKey(file_get_contents('privatekey.txt'));
echo $rsa->decrypt(file_get_contents('ciphertext.txt'));
?>

Encryption with OAEP padding:

<?php
include('Crypt/RSA.php');

$rsa = new Crypt_RSA();
$rsa->loadKey(file_get_contents('privatekey.txt'));
$rsa->loadKey($rsa->getPublicKey());
echo $rsa->encrypt('1234567890');
?>

openssl rsautl -inkey privatekey.txt -decrypt -oaep -in ciphertext.txt -out plaintext.txt

phpseclib can be downloaded from http://phpseclib.sourceforge.net/

Good luck!

The Crypt_RSA on PEAR is not using PKCS#1 encoding. I suspect that is why .NET is giving you an error message.

As an example of it breaking, I created a php script using Crypt_RSA to encrypt the string "1234567" (I'll skip showing key loading):

print $rsa_obj->encryptBinary("1234567", $key_pair->getPublicKey());

Taking the output of that and piping it through the openssl command line tool gives the following error:

$ ./crypt | openssl rsautl -inkey privkey.pem -decrypt
RSA operation error
18437:error:04065084:rsa routines:RSA_EAY_PRIVATE_DECRYPT:data too large for modulus:fips_rsa_eay.c:558:

openssl expects PKCS#1 padding by default, but adding the -raw (no padding) flag to openssl doesn't help either.

Using the openssl extension in php gives the proper padding (defaults to PKCS#1, others available):

$pem = file_get_contents("pubkey.pem");
$key = openssl_pkey_get_public($pem);

$encrypted = "";
if(openssl_public_encrypt("1234567", $encrypted, $key)) {
  print $encrypted;
} else {
  print "failed\n";
}

And the decrypt code in php:

$pem = file_get_contents("privkey.pem");
$key = openssl_pkey_get_private($pem);

$enc_data = file_get_contents("openssl.crypted");
$decrypted = "";
if(openssl_private_decrypt($enc_data, $decrypted, $key)) {
  print "$decrypted\n";
} else {
  print "failed\n";
}

Certificates in the context of RSA are X.509 certificates, which are the RSA keys plus data about those keys. X.509 certificates are used in SSL, but are not required to use RSA.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!