Dot-Net

“System.Security.Cryptography.CryptographicException:密鑰錯誤。”對於 RSACryptoServiceProvider.Decrypt()

  • March 16, 2022

我正在玩 RSA 加密/解密和證書。具體來說,我嘗試使用證書的公鑰進行加密,然後在嘗試使用與該證書對應的私鑰進行解密時,出現錯誤:

System.Security.Cryptography.CryptographicException: Bad Key.

  at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
  at System.Security.Cryptography.RSACryptoServiceProvider.DecryptKey(SafeKeyHandle pKeyContext, Byte[] pbEncryptedKey, Int3
2 cbEncryptedKey, Boolean fOAEP, ObjectHandleOnStack ohRetDecryptedKey)
  at System.Security.Cryptography.RSACryptoServiceProvider.Decrypt(Byte[] rgb, Boolean fOAEP)

程式碼是:

private void TestCertificates2()
{
   //////////////////////////////////////////////////////
   // SENDER CODE
   //////////////////////////////////////////////////////

   // get certificate
   var certSender = new X509Certificate2(@"C:\Test.cer");

   // encrypt with public key
   var providerSender = (RSACryptoServiceProvider)certSender.PublicKey.Key;
   var plainSender = Encoding.Default.GetBytes("this is plain text");
   var cipher = providerSender.Encrypt(plainSender, false);

   //////////////////////////////////////////////////////
   // RECEIVER CODE
   //////////////////////////////////////////////////////

   // get certificate
   var store = new X509Store("MY", StoreLocation.LocalMachine);
   store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
   var certReceiver = store.Certificates.Find(X509FindType.FindBySubjectName, "Test Subject", false)[0];

   // decrypt with private key
   var providerReceiver = (RSACryptoServiceProvider)certReceiver.PrivateKey;
   var plainReceiver = providerReceiver.Decrypt(cipher, false);

   // check they are same
   if (plainSender.Equals(plainReceiver))
   {
       Console.WriteLine("Same!");
   }
}

作為參考,證書是通過創建和安裝的

makecert.exe Test.cer -n "CN=Test Subject" -sr LocalMachine -ss My

有人能發現我做錯了什麼嗎?提前致謝!

好的,發現問題所在:需要告訴 makecert 1)證書的主題密鑰類型是“Exchange”2)將私鑰標記為可導出

所以 makecert 呼叫看起來像

makecert.exe Test.cer -r -n "CN=Test Subject" -sr LocalMachine -ss My -sky Exchange -pe

如果您無法自己生成證書,請確保通過允許您設置“密鑰交換”標誌的命令行導入它。

certutil -importPFX certificate.pfx AT_KEYEXCHANGE,NoExport

通過 GUI 嚮導導入將始終使用 AT_SIGNATURE,然後您只能使用私鑰進行簽名,不能用於加密!

引用自:https://stackoverflow.com/questions/4661637