这是此处未回答问题的副本:Using an RSA Public Key to decrypt a string that was encrypted using RSA Private Key
您可以看到作者使用此处的一些代码找到了解决方案:http: //www.codeproject.com/KB/security/PrivateEncryption.aspx
使用该链接中的代码看起来很有希望。唯一缺少的是填充。我通常使用 PKCS1.5 填充,这是 OpenSSL RSA 的默认值。
我知道这个问题的答案非常接近。我知道唯一阻止解密的是加密的 openssl 密文上的 pkcs1.5 填充。
我很惊讶地发现关于这个主题的信息很少,因为在很多情况下,您需要服务器来加密某些东西、签署某些东西等,并让客户端应用程序使用公钥验证、解密等。
我还广泛尝试使用 RSACryptoServiceProvider 来验证使用 OpenSSL 加密产生的哈希值。例如,我会使用明文的 SHA256 哈希进行私钥加密,然后尝试对该签名进行 RSACryptoServiceProvider 验证,但它不起作用。我认为 MS 这样做的方式是非标准的,并且可能有特殊的定制在起作用。
所以,另一种选择是这个问题,它只是获取私钥加密的密文并使用C#对其进行解密,从而验证它的真实性。可以结合散列来为服务器签名并在客户端验证的数据对象创建一个简单的签名验证系统。
我查看了 PKCS1 RFC、OpenSSL rsa 源代码和其他项目,在进行 RSA 解密时,我无法得到关于如何考虑 PKCS1 填充的可靠答案。我无法找到他们在 OpenSSL 源代码中处理 PKCS1 填充的位置,否则,我现在可能已经有了答案。
另外,这是我的第一个问题,我知道这是一个未回答问题的重复,那么,该怎么办?我也用谷歌搜索过,什么也没找到。
我不明白的另一件事是为什么我的解密方法不起作用。由于解密后填充被删除,我的解密数据应该类似于纯文本,甚至不接近。因此,我几乎可以肯定 pkcs1 填充意味着其他事情正在发生,特别是对于密文,这意味着必须在解密之前对密文进行预处理以删除填充元素。
也许简单地过滤密文以删除填充元素是这里最简单的解决方案......
这是我的解密方法:
public static byte[] PublicDecryption(this RSACryptoServiceProvider rsa, byte[] cipherData)
{
if (cipherData == null)
throw new ArgumentNullException("cipherData");
BigInteger numEncData = new BigInteger(cipherData);
RSAParameters rsaParams = rsa.ExportParameters(false);
BigInteger Exponent = GetBig(rsaParams.Exponent);
BigInteger Modulus = GetBig(rsaParams.Modulus);
BigInteger decData = BigInteger.ModPow(numEncData, Exponent, Modulus);
byte[] data = decData.ToByteArray();
byte[] result = new byte[data.Length - 1];
Array.Copy(data, result, result.Length);
result = RemovePadding(result);
Array.Reverse(result);
return result;
}
private static byte[] RemovePadding(byte[] data)
{
byte[] results = new byte[data.Length - 4];
Array.Copy(data, results, results.Length);
return results;
}