Search code examples
c#cryptographybouncycastlex509certificate2pkcs#7

Unable to fetch private key from .net x509certificate2 object to bouncycastle AsymmetricCipherKeyPair


I was trying to get keypair for pkcs-7 signature an X509Certificate2 object from this code.

RSACryptoServiceProvider key = (RSACryptoServiceProvider)Cert.PrivateKey;
RSAParameters rsaparam = key.ExportParameters(true);
AsymmetricCipherKeyPair keypair = DotNetUtilities.GetRsaKeyPair(rsaparam);

This works fine if X509Certificate2 object is created using .pfx file like this

X509Certificate2 cert = new X509Certificate2(".pfx file path", "password");

it works fine. but when the certificate is listed from certificate store like this

 X509Certificate2 cert;
 X509Store UserCertificateStore = new X509Store("My");
 UserCertificateStore.Open(OpenFlags.ReadOnly);
 var certificates = UserCertificateStore.Certificates;
 foreach (var certificate in certificates)
 {
    if (certificate.Thumbprint==thumbprint)
    {
       cert=certificate;
       break;
    }
 }

it throws an exception with the message - Key not valid for use in specified state.

after @Crypt32 answer tried using RSA method sign hash

RSACryptoServiceProvider csp = (RSACryptoServiceProvider)cert.PrivateKey;

using (SHA256Managed sHA256 = new SHA256Managed())
{
    byte[] hash = sHA256.ComputeHash(data);
    return csp.SignHash(hash, CryptoConfig.MapNameToOID("SHA256"));
}

but the signature was not in PKCS#7 format


Solution

  • This is because BouncyCastle attempts to get raw key material (literally, export) from .NET object while actual key is not marked as exportable. In Windows systems, keys are stored in cryptographic service providers which control all key operations. When you need to perform a specific cryptographic operation, you are asking CSP to do a job and it does without having to expose key material to you. If the key was imported/generated in CSP as exportable, you can ask CSP to export key material. If this flag was not set, CSP won't give you the key.

    I don't know how BouncyCastle works, but if it expects raw key material, then you need exportable private key in your certificate.