15

Normally when I grab an X509Certificate2 out of my keystore I can call .PrivateKey to retrieve the cert's private key as an AsymmetricAlgorithm. However I have decided to use Bouncy Castle and its instance of X509Certificate only has a getPublicKey(); I cannot see a way to get the private key out of the cert. Any ideas?

I get the an X509Certificate2 from my Windows-MY keystore then use:

//mycert is an X509Certificate2 retrieved from Windows-MY Keystore
X509CertificateParser certParser = new X509CertificateParser();
X509Certificate privateCertBouncy = certParser.ReadCertificate(mycert.GetRawCertData());
AsymmetricKeyParameter pubKey = privateCertBouncy.GetPublicKey();
//how do i now get the private key to make a keypair?

Is there anyway to convert a AsymmetricAlgorithm(C# private key) to a AsymmetricKeyParameter(bouncycastle private key)?

Petey B
  • 11,439
  • 25
  • 81
  • 101

3 Answers3

34
Akp = Org.BouncyCastle.Security.DotNetUtilities.GetKeyPair(this.Certificate.PrivateKey).Private;
majkinetor
  • 8,730
  • 9
  • 54
  • 72
  • 2
    Doing this I just get ```Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException: 'The requested operation is not supported.'``` – gakera Aug 24 '21 at 17:14
22

Don't know BouncyCastle that much but it seems to me that the simple thing to do is to recreate the key based on the key parameters.

public static AsymmetricKeyParameter TransformRSAPrivateKey(
    AsymmetricAlgorithm privateKey)
{
    RSACryptoServiceProvider prov = privateKey as RSACryptoServiceProvider;
    RSAParameters parameters = prov.ExportParameters(true);
    
    return new RsaPrivateCrtKeyParameters(
        new BigInteger(1,parameters.Modulus),
        new BigInteger(1,parameters.Exponent),
        new BigInteger(1,parameters.D),
        new BigInteger(1,parameters.P),
        new BigInteger(1,parameters.Q),
        new BigInteger(1,parameters.DP),
        new BigInteger(1,parameters.DQ),
        new BigInteger(1,parameters.InverseQ));
}

You can call the code by using

AsymmetricKeyParameter bouncyCastlePrivateKey = 
    TransformRSAPrivateKey(mycert.PrivateKey);

Obviously this assumes that the certificate includes a RSA Key but the same result can be achieved for DSA with DSACryptoServiceProvider and DSAParameters.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
CriGoT
  • 994
  • 7
  • 12
3

Find .NET X509Certificate2:

X509Certificate2 cert = this.FindCertificate(certificateFriendlyName);

Parse it to BouncyCastle certificate and use X509Certificate2Signature to get signature:

var parser = new X509CertificateParser();
var bouncyCertificate = parser.ReadCertificate(cert.RawData);
var algorithm = DigestAlgorithms.GetDigest(bouncyCertificate.SigAlgOid);
var signature = new X509Certificate2Signature(cert, algorithm);
Gabrielius
  • 1,045
  • 12
  • 18