开发者

"System.Security.Cryptography.CryptographicException: Bad Key." for RSACryptoServiceProvider.Decrypt()

开发者 https://www.devze.com 2023-02-04 04:33 出处:网络
I\'m playing with RSA encryption/decryption and certificates. Here specifically, I try to encrypt with the public key of a certificate, and then, when trying to decrypt with the private key correspond

I'm playing with RSA encryption/decryption and certificates. Here specifically, I try to encrypt with the public key of a certificate, and then, when trying to decrypt with the private key corresponding to that certificate, get an error:

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)

Code is:

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 = pro开发者_开发知识库viderSender.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!");
    }
}

For reference, certificate was created and installed through

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

Can someone spot what I am doing wrong? Thanks in advance!


Ok, found what the issue is: needed to tell makecert 1) that's certificate's subject key type is for "Exchange" 2) to mark private key as exportable

so makecert call looks like

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


If you cannot generate the certificate yourself, ensure to import it via the command line which allows you to set the "key exchange" flag.

certutil -importPFX certificate.pfx AT_KEYEXCHANGE,NoExport

Importing via the GUI wizard will always use AT_SIGNATURE, and then you can only use the private key for signing, NOT for encryption!

0

精彩评论

暂无评论...
验证码 换一张
取 消