I create a certificate using BouncyCastle
var keypairgen = new RsaKeyPairGenerator();
keypairgen.Init(new KeyGenerationParameters(new Secure
For anyone trying to export the X509Certificate2 to PKCS12 and preserve the private key. This is what I had to do:
// Convert BouncyCastle X509 Certificate to .NET's X509Certificate
var cert = DotNetUtilities.ToX509Certificate(certificate);
var certBytes = cert.Export(X509ContentType.Pkcs12, "password");
// Convert X509Certificate to X509Certificate2
var cert2 = new X509Certificate2(certBytes, "password");
// Convert BouncyCastle Private Key to RSA
var rsaPriv = DotNetUtilities.ToRSA(issuerKeyPair.Private as RsaPrivateCrtKeyParameters);
// Setup RSACryptoServiceProvider with "KeyContainerName" set
var csp = new CspParameters();
csp.KeyContainerName = "KeyContainer";
var rsaPrivate = new RSACryptoServiceProvider(csp);
// Import private key from BouncyCastle's rsa
rsaPrivate.ImportParameters(rsaPriv.ExportParameters(true));
// Set private key on our X509Certificate2
cert2.PrivateKey = rsaPrivate;
// Export Certificate with private key
File.WriteAllBytes(@"C:\Temp\cert.pfx", cert2.Export(X509ContentType.Pkcs12, "password"));
I would like to share my method:
pfx to System.Security.Cryptography.X509Certificates.X509Certificate2 using bouncy castle.
public static X509Certificate2 OpenCertificate(string pfxPath, string contrasenia)
{
System.Security.Cryptography.X509Certificates.X509Certificate2 x509 = default(System.Security.Cryptography.X509Certificates.X509Certificate2);
MemoryStream ms = new MemoryStream(File.ReadAllBytes(pfxPath));
Org.BouncyCastle.Pkcs.Pkcs12Store st = new Org.BouncyCastle.Pkcs.Pkcs12Store(ms, contrasenia.ToCharArray());
var alias = st.Aliases.Cast<string>().FirstOrDefault(p => st.IsCertificateEntry(p));
Org.BouncyCastle.Pkcs.X509CertificateEntry keyEntryX = st.GetCertificate(alias);
x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(DotNetUtilities.ToX509Certificate(keyEntryX.Certificate));
alias = st.Aliases.Cast<string>().FirstOrDefault(p => st.IsKeyEntry(p));
Org.BouncyCastle.Pkcs.AsymmetricKeyEntry keyEntry = st.GetKey(alias);
System.Security.Cryptography.RSACryptoServiceProvider intermediateProvider = (System.Security.Cryptography.RSACryptoServiceProvider)Org.BouncyCastle.Security.DotNetUtilities.ToRSA((Org.BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParameters)keyEntry.Key);
x509.PrivateKey = intermediateProvider;
return x509;
}
Just be be verbose, this is the full code to add after creation of X509Certificate2 certificate:
RSA rsaPriv = DotNetUtilities.ToRSA(keypair.Private as RsaPrivateCrtKeyParameters);
certificate.PrivateKey = rsaPriv;
(Which of course can be optimised into one line.)
If you look at the links from this question, you should be able to use something similar to DotNetUtilities.ToRSA(...)
and put its return value into the X509Certificate2
's PrivateKey
.