问题
I create a certificate using BouncyCastle
var keypairgen = new RsaKeyPairGenerator();
keypairgen.Init(new KeyGenerationParameters(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.
回答1:
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
.
回答2:
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.)
回答3:
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"));
回答4:
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;
}
来源:https://stackoverflow.com/questions/6128541/bouncycastle-privatekey-to-x509certificate2-privatekey