C# – Decrypt with PrivateKey X.509 Certificate

ccertificatenetprivate-key

I have a problem to decrypt a message usgin X.509 Certificate.

I generate my certificate with makecert with this options:

makecert -r -pe -n "CN=MyCertificate" -ss CA -sr CurrentUser -a sha1 -sky signature -cy authority -sv CA.pvk CA.cer

And the PrivateKey was "mypassword".

My problem is when I want to decrypt a message encrypt with previous certificate in c#.

I found this class http://blog.shutupandcode.net/?p=660, but in the X509Decrypt method allways the PrivateKey is null.

public static byte[] X509Decrypt(byte[] data, string certificateFile, string password)
{
    // load the certificate and decrypt the specified data
    using (var ss = new System.Security.SecureString())
    {
        foreach (var keyChar in password.ToCharArray())
            ss.AppendChar(keyChar);

        // load the password protected certificate file
        X509Certificate2 cert = new X509Certificate2(certificateFile, ss);

        using (RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PrivateKey)
        {
            return rsa.Decrypt(data, true);
        }    
    }
}

I tried passing the certificate file (.cer)

X509DecryptString(token, @"c:\CA.cer", "mypassword");

And passing the pvk file (.pvk)

X509DecryptString(token, @"c:\CA.pvk", "mypassword");

But allways have that the PrivateKey property is null.

Can anyone guide me to decrypt the message using the pvk file?

Thanks,

Jose

Best Answer

The certificate itself only contains the public key (+ some data), but not the private key. (It's very unlikely that the RSA private key is "mypassword". The password that protects your private key may be "mypassword", but the private key itself (more specifically the private exponent, in RSA) will be a rather long number.)

As a result (because CA.cer only contains the certificate), X509DecryptString(token, @"c:\CA.cer", "mypassword") will almost certainly not work.

X509DecryptString(token, @"c:\CA.pvk", "mypassword"); could work in principle, but you're creating a X509Certificate2 object from it, and it still needs the certificate and the private key. You should be able to load that from a PKCS#12 container (.p12/.pfx).

To create this container, you can use pvk2pfx:

pvk2pfx -spc CA.cer -pvk CA.pvk -pfx CA.pfx

(If you don't specify -pfx CA.pfx, it will launch the interactive interface, in which case you need to tick the box to export the private key.)

Then, try to decrypt using that pfx/p12 file instead.