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

发布于 2024-08-28 10:59:32 字数 272 浏览 2 评论 0原文

在 PHP 中,我对要由 .NET 应用程序解密的消息进行 RSA 加密...但我不断从 .NET 收到“错误密钥”异常...

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

我想最简单的问题是 -> “坏密钥”是否意味着它无法解密该消息? IE,它没有正确加密吗?

更难的问题是-> RSA 加密有什么特殊之处会导致 .NET 和 PHP 之间出现异常吗?

In PHP I am RSA encrypting a message to be decrypted by .NET application... but I keep getting a "Bad Key" exception from .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...

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?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

瞎闹 2024-09-04 10:59:32

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

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

使用 PKCS#1 填充进行解密:

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'));
?>

使用 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

使用 OAEP 填充解密:

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'));
?>

使用 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

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

祝你好运!

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!

一杆小烟枪 2024-09-04 10:59:32

PEAR 上的 Crypt_RSA 不使用 PKCS#1 编码。我怀疑这就是 .NET 向您提供错误消息的原因。

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

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

获取该脚本的输出并通过 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 默认情况下期望 PKCS#1 填充,但向 openssl 添加 -raw (无填充)标志也没有帮助。

在 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";
}

以及 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";
}

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文