Dot-Net
“System.Security.Cryptography.CryptographicException:密鑰錯誤。”對於 RSACryptoServiceProvider.Decrypt()
我正在玩 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,然後您只能使用私鑰進行簽名,不能用於加密!