使用 openssl_public_encrypt 验证 RSA 签名对 .NET 签名字符串失败

Posted

技术标签:

【中文标题】使用 openssl_public_encrypt 验证 RSA 签名对 .NET 签名字符串失败【英文标题】:Veryifying RSA signature using openssl_public_decrypt failing for .NET signed string 【发布时间】:2012-08-26 23:13:25 【问题描述】:

我正在尝试使用 X509Certificate2 和 RSACryptoServiceProvider 以及 php OpenSSL 命令来实现双向相互安全。

从 PHP 向 C# 发送消息似乎一切正常,.NET 服务器上的 RSACryptoServiceProvider 可以使用它自己的私钥解密消息并使用 PHP 服务器的公钥验证签名。

但反过来说,.NET 到 PHP,使用“openssl_public_decrypt”来验证 .NET 服务器的签名会造成麻烦。它只是返回假。 'openssl_private_decrypt' 可以很好地使用 PHP 服务器的私钥解密加密数据。

我使用 openssl(.key 和 .crt)为两台服务器创建了 RSA (2048) 自签名证书,然后创建了一个 .pfx 以用作 .NET 代码中的私钥。

我想知道这里有什么问题。我在 .NET 和 PHP 服务器上都使用默认设置进行加密/解密。当您使用 .pfx 加密某些内容时,加密/解密机制是否不同?或者 openssl_public_decrypt 是否期望与 RSACryptoServiceProvider 给你的加密不同?

任何帮助都会很棒,因为我不确定问题出在哪里。

【问题讨论】:

【参考方案1】:

openssl_public_decrypt 对公钥的格式非常敏感,并且不支持与 openssl_private_decrypt 一样多的填充方案。

我的建议:使用phpseclib, a pure PHP RSA implementation。一个例子:

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

$rsa = new Crypt_RSA();
$rsa->loadKey('...'); // public key

$plaintext = '...';

$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
$ciphertext = $rsa->encrypt($plaintext);

$rsa->loadKey('...'); // private key
echo $rsa->decrypt($ciphertext);
?>

它支持比 OpenSSL 更多的密钥格式,从 XML 签名格式的密钥到 PuTTY 密钥等。

【讨论】:

以上是关于使用 openssl_public_encrypt 验证 RSA 签名对 .NET 签名字符串失败的主要内容,如果未能解决你的问题,请参考以下文章

PHP openssl_public_encrypt“密钥参数不是有效密钥”

php rsa加密 已有明文和公钥 只需加密

php使用RSA加密后乱码?

PHP加解密相关函数

测试使用

第一篇 用于测试使用