RSA在PHP中加密以在.NET中解密

时间:2022-03-31 18:27:30

In PHP I am RSA encrypting a message to be decrypted by .NET application... but I keep getting a "Bad Key" exception from .NET....

在PHP中我是RSA加密要由.NET应用程序解密的消息...但我不断从.NET获得“坏键”异常....

For RSA encryption, I am using PEAR class Crypt_RSA-> encrypting with the public key (which is a modulus, exponent pair) I get from working encryption system in .NET...

对于RSA加密,我使用PEAR类Crypt_RSA->加密公钥(这是一个模数,指数对)我从.NET中的工作加密系统获得...

I guess the easiest question would be-> does "Bad Key" mean it is not able to decrypt the message whatsoever? IE, it is not encrypted correctly?

我想最容易的问题是 - >“坏键”是否意味着它无法解密消息? IE,它没有正确加密?

The harder question is-> Is there anything specific about RSA encryption that causes quirks between .NET and PHP?

更难的问题是 - > RSA加密是否有任何特定的东西导致.NET和PHP之间的怪癖?

2 个解决方案

#1


14  

Security Warning: Use OAEP, not PKCS#1.

安全警告:使用OAEP,而不是PKCS#1。

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

如果您想使用不需要openssl扩展的解决方案,请尝试使用phpseclib的Crypt_RSA。示例如下:

Decryption with PKCS#1 padding:

用PKCS#1填充解密:

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

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:

使用PKCS#1填充加密:

<?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

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

Decryption with OAEP padding:

使用OAEP填充解密:

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

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:

使用OAEP填充加密:

<?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

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

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

phpseclib可以从http://phpseclib.sourceforge.net/下载

Good luck!

祝你好运!

#2


3  

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

PEAR上的Crypt_RSA不使用PKCS#1编码。我怀疑这就是为什么.NET会给你一个错误信息。

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):

作为它打破的一个例子,我使用Crypt_RSA创建了一个PHP脚本来加密字符串“1234567”(我将跳过显示密钥加载):

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:

获取它的输出并通过openssl命令行工具管道它会产生以下错误:

$ ./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.

openssl默认使用PKCS#1填充,但是向openssl添加-raw(无填充)标志也无济于事。

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

在php中使用openssl扩展可以提供正确的填充(默认为PKCS#1,其他可用):

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

和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.

RSA上下文中的证书是X.509证书,它们是RSA密钥以及有关这些密钥的数据。 X.509证书用于SSL,但不要求使用RSA。

#1


14  

Security Warning: Use OAEP, not PKCS#1.

安全警告:使用OAEP,而不是PKCS#1。

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

如果您想使用不需要openssl扩展的解决方案,请尝试使用phpseclib的Crypt_RSA。示例如下:

Decryption with PKCS#1 padding:

用PKCS#1填充解密:

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

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:

使用PKCS#1填充加密:

<?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

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

Decryption with OAEP padding:

使用OAEP填充解密:

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

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:

使用OAEP填充加密:

<?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

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

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

phpseclib可以从http://phpseclib.sourceforge.net/下载

Good luck!

祝你好运!

#2


3  

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

PEAR上的Crypt_RSA不使用PKCS#1编码。我怀疑这就是为什么.NET会给你一个错误信息。

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):

作为它打破的一个例子,我使用Crypt_RSA创建了一个PHP脚本来加密字符串“1234567”(我将跳过显示密钥加载):

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:

获取它的输出并通过openssl命令行工具管道它会产生以下错误:

$ ./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.

openssl默认使用PKCS#1填充,但是向openssl添加-raw(无填充)标志也无济于事。

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

在php中使用openssl扩展可以提供正确的填充(默认为PKCS#1,其他可用):

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

和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.

RSA上下文中的证书是X.509证书,它们是RSA密钥以及有关这些密钥的数据。 X.509证书用于SSL,但不要求使用RSA。