BouncyCastle PrivateKey To X509Certificate2 PrivateKey
I create a certificate using BouncyCastle
var keypairgen = new RsaKeyPairGenerator();
keypairgen.Init(new KeyGenerationP开发者_Python百科arameters(new SecureRandom(new CryptoApiRandomGenerator()), 1024));
var keypair = keypairgen.GenerateKeyPair();
var gen = new X509V3CertificateGenerator();
var CN = new X509Name("CN=" + certName);
var SN = BigInteger.ProbablePrime(120, new Random());
gen.SetSerialNumber(SN);
gen.SetSubjectDN(CN);
gen.SetIssuerDN(CN);
gen.SetNotAfter(DateTime.Now.AddYears(1));
gen.SetNotBefore(DateTime.Now.Subtract(new TimeSpan(7,0,0,0)));
gen.SetSignatureAlgorithm("MD5WithRSA");
gen.SetPublicKey(keypair.Public);
gen.AddExtension(
X509Extensions.AuthorityKeyIdentifier.Id,
false,
new AuthorityKeyIdentifier(
SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keypair.Public),
new GeneralNames(new GeneralName(CN)),
SN
));
gen.AddExtension(
X509Extensions.ExtendedKeyUsage.Id,
false,
new ExtendedKeyUsage(new ArrayList()
{
new DerObjectIdentifier("1.3.6.1.5.5.7.3.1")
}));
var newCert = gen.Generate(keypair.Private);
This end with
X509Certificate2 certificate = new X509Certificate2(DotNetUtilities.ToX509Certificate((Org.BouncyCastle.X509.X509Certificate)newCert));
Now, because my assignment tells me to store both the Certificate and the PrivateKey in the X509Certificate2 object I need a way to convert the keypair.Private into a X509Certificate2.Private. Any ideas?
Thanks.
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
.
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;
}
精彩评论