BouncyCastle私钥转换为X509Certificate2私钥

14

我使用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);
这个结束于

X509Certificate2 certificate = new X509Certificate2(DotNetUtilities.ToX509Certificate((Org.BouncyCastle.X509.X509Certificate)newCert));

现在,因为我的任务要求我将证书和私钥都存储在X509Certificate2对象中,所以我需要一种将keypair.Private转换为X509Certificate2.Private的方法。有什么想法吗?

谢谢。


1
密钥对的私钥类型是什么?你看过AsymmetricAlgorithm.Create()吗? - Dustin Davis
编辑:好的,.Create()可以工作,但在keypair.private上使用时返回null。它是AsymmetricKeyParameter类型。 - barjed
嗨,感谢您提供可用的代码来创建X509Certificate2!那真的帮了很多忙! - Arsen Zahray
4个回答

8

为了详细说明,这是在创建X509Certificate2证书后添加的完整代码:

RSA rsaPriv = DotNetUtilities.ToRSA(keypair.Private as RsaPrivateCrtKeyParameters);
certificate.PrivateKey = rsaPriv;

(当然,这可以优化成一行。)

6

对于任何尝试将X509Certificate2导出到PKCS12并保留私钥的人,这是我所做的:

        // 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"));

1
这是我找到的唯一方法,可以获取与证书关联的私钥,并且能够在以后检索它。 - Jon Norton

6
如果你查看来自这个问题的链接,你应该能够使用类似于DotNetUtilities.ToRSA(...)的东西,并将其返回值放入X509Certificate2PrivateKey中。

0
我想分享我的方法:
使用Bouncy Castle将pfx转换为System.Security.Cryptography.X509Certificates.X509Certificate2。
        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;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接