使用X509证书的RSACryptoServiceProvider在C#中的应用

7
我正在使用由makecert生成的既有私钥又有公钥的证书。Java端使用此公钥加密数据,而.NET则将其解密回来。
我正在尝试解密Java加密的64位编码字符串并得到了坏数据。
为了查看在.NET端是否一切正常,我首先尝试使用公钥进行加密,然后使用相同证书的私钥进行解密。我的代码如下。
X509Certificate2 cert = GetCert(key, StoreName.My, StoreLocation.LocalMachine);
RSACryptoServiceProvider provider =  (RSACryptoServiceProvider)cert.PrivateKey;

RSACryptoServiceProvider publicprovider = (RSACryptoServiceProvider)cert.PublicKey.Key;

if (cert.HasPrivateKey)
    MessageBox.Show("Got private key");

byte[] encrypted = publicprovider.Encrypt(Encoding.UTF8.GetBytes(text), false);
byte[] decryptedBytes = provider.Decrypt(encrypted, false); 

即使在这里我也遇到了错误。我错过了什么吗?
证书看起来具有公钥和私钥,是有效的。

什么错误?在哪一行? - H H
异常:坏数据。没有更多的内部异常,当调用byte[] decryptedBytes = provider.Decrypt(encrypted, false);时。 - bkhanal
4个回答

5

我曾经遇到过自签名证书的同样问题,解决方法是我在生成证书时使用了 -sky exchange 而不是 -sky signature (你可以用 signature 签名,用 exchange 加密/解密)

以下是我的完整 makecert 命令:

makecert -r -pe -a sha1 -n "CN=MyName" -ss my -sr CurrentUser -sky exchange

4
以下代码对我来说运行良好:
        RSACryptoServiceProvider privateKey = new RSACryptoServiceProvider();
        privateKey.FromXmlString("<RSAKeyValue><Modulus>wL8s+C8SnnlaaqR+VsyijmxOJOARNa4o7ZNsqfy3+9J9Ol2JNSjjMfQWoUnFtClzJBlZhU5KtuazQe8ZKXTX9YvKoJdRhlsonZkC04qiTMdO/FZIH00GrCRxeQ7XDnQnvPB9Bdsvs//7zrY3f7eLIkpIyK9cQHU+5jjJd5IT0eE=</Modulus><Exponent>AQAB</Exponent><P>83xxN7jvpg5z16pxz2tIQIdqd/EfmikR9Q2TjG2tosWkUSvtyx0xHZ9EqdTUbSGZZ+jgrabzkafYc7Mplylwew==</P><Q>yqcnYSZEXHwJvRWi2V09PNEENTozQZywcFptUUGar9TciaQvoNv3lpnfzUKNBRdhzq4lImxkamajZlTWE5buUw==</Q><DP>37HqilkbwyHwB6mOGhPkM3S1ujAK6qTk3JB2iEOTjMGrru9+7maJYz+Z47Wm3ARMXgyzrpZ9m8nqsJFfmoL11Q==</DP><DQ>v285tv8kMs2FkZYfuP/oOkwkkneBNejjj68Md2bmzlThZDCyQV2pvB1tmgPVHUsiPNCrCaKlFRISJzfa5rR8Ow==</DQ><InverseQ>fgJE2TRe/SS+YqW0/I+FtHrdfbbao0/R3pHD4r4oceZQUemlBgZ7DxOAetebHKthlOdjGkmfWYB8EU4XoWggqw==</InverseQ><D>FMLCwjy3wbAKiCANp6XFAJgz1o7365NFv0k41BpvasViTa4TgFFWH2ROJ7M9g0lPqJy+YrhrHcY9mqV5TVjTheQp0JeckrgO2B39XngPMAMMdne3rWGpf0Pfbj3FLfchMk6XYDXSZzCS2CmSeRA4aBMb+4R3YurixyJLrnGRMH0=</D></RSAKeyValue>");
        RSACryptoServiceProvider publicKey = new RSACryptoServiceProvider();
        publicKey.FromXmlString("<RSAKeyValue><Modulus>wL8s+C8SnnlaaqR+VsyijmxOJOARNa4o7ZNsqfy3+9J9Ol2JNSjjMfQWoUnFtClzJBlZhU5KtuazQe8ZKXTX9YvKoJdRhlsonZkC04qiTMdO/FZIH00GrCRxeQ7XDnQnvPB9Bdsvs//7zrY3f7eLIkpIyK9cQHU+5jjJd5IT0eE=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>");

        {
            string text = "foo";
            byte[] encrypted = publicKey.Encrypt(Encoding.UTF8.GetBytes(text), false);
            byte[] decryptedBytes = privateKey.Decrypt(encrypted, false);
        }

请确认导出的私钥是否来自于cert.PrivateKey,公钥是否来自于cert.PublicKey.Key?


当证书返回时,它已经生成了AES对称密钥。 我没有使用需要先创建公私钥并基于此生成提供程序的实现。这使用makecert。 上面的代码没有出错,但具有128个字符模数... - bkhanal
1
当证书返回时,它已经生成了AES对称密钥。我不太明白这是什么意思。AES密钥生成在哪里?在您的代码示例中我看不到它。 - Rasmus Faber
如果您使用makecert工具创建证书,它将包含私钥和公钥。因此,您可以前往商店获取私钥和公钥。我还没有在代码中添加获取私钥和公钥的功能。 - bkhanal
但是我在谈论使用AES对称密钥,RSA非对称密钥对应该加密它而不是直接加密文本。我意识到makecert工具生成RSA密钥。 - Rasmus Faber

2

1

我终于找到了问题所在。我没有将密钥放入makecert中,以将其定义为RSA加密密钥。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接