即时生成自签名证书

wak*_*neo 34 .net c# bouncycastle ssl-certificate x509certificate

我四处搜寻,但没有找到一个明确的例子. 我想按照以下步骤以编程方式(c#)创建自签名(自我)可信证书:

步骤1:动态 创建根CA证书并将其添加到"受信任的根证书颁发机构"文件夹中的证书存储区

我想要完成这个命令行工具的功能:

makecert.exe -sk RootCA -sky签名-pe -n CN = MY_CA -r -sr LocalMachine -ss根MyCA.cer

第2步: 根据以前创建的根CA证书创建证书,并将其放入证书存储区"Personal"文件夹中

我想要完成这个命令行工具的功能:

makecert.exe -sk server -sky exchange -pe -n CN = 127.0.0.1 -ir LocalMachine -is Root -ic MyCA.cer -sr LocalMachine -ss My MyCertificate.cer

我想得到这个:
在此输入图像描述

我这样做了(参见下面的代码 - 第1步),不知道如何制作STEP2,任何帮助都将不胜感激.目标计算机是Windows XP/Seven. 我尝试了纯粹的.net方法和BouncyCastle库.

makecert.exe -sk RootCA -sky signature -pe -n CN=MY_CA -r -sr LocalMachine -ss Root MyCA.cer
Run Code Online (Sandbox Code Playgroud)

pep*_*epo 32

我编写了首先执行root证书的答案,然后发出了最终实体证书.以下是通过弹性生成自签名证书的一些示例:

public static X509Certificate2 GenerateSelfSignedCertificate(string subjectName, string issuerName, AsymmetricKeyParameter issuerPrivKey,  int keyStrength = 2048)
{
    // Generating Random Numbers
    var randomGenerator = new CryptoApiRandomGenerator();
    var random = new SecureRandom(randomGenerator);

    // The Certificate Generator
    var certificateGenerator = new X509V3CertificateGenerator();

    // Serial Number
    var serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);
    certificateGenerator.SetSerialNumber(serialNumber);

    // Signature Algorithm
    const string signatureAlgorithm = "SHA256WithRSA";
    certificateGenerator.SetSignatureAlgorithm(signatureAlgorithm);

    // Issuer and Subject Name
    var subjectDN = new X509Name(subjectName);
    var issuerDN = new X509Name(issuerName);
    certificateGenerator.SetIssuerDN(issuerDN);
    certificateGenerator.SetSubjectDN(subjectDN);

    // Valid For
    var notBefore = DateTime.UtcNow.Date;
    var notAfter = notBefore.AddYears(2);

    certificateGenerator.SetNotBefore(notBefore);
    certificateGenerator.SetNotAfter(notAfter);

    // Subject Public Key
    AsymmetricCipherKeyPair subjectKeyPair;
    var keyGenerationParameters = new KeyGenerationParameters(random, keyStrength);
    var keyPairGenerator = new RsaKeyPairGenerator();
    keyPairGenerator.Init(keyGenerationParameters);
    subjectKeyPair = keyPairGenerator.GenerateKeyPair();

    certificateGenerator.SetPublicKey(subjectKeyPair.Public);

    // Generating the Certificate
    var issuerKeyPair = subjectKeyPair;

    // Selfsign certificate
    var certificate = certificateGenerator.Generate(issuerPrivKey, random);

    // Corresponding private key
    PrivateKeyInfo info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private);


    // Merge into X509Certificate2
    var x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate.GetEncoded());

    var seq = (Asn1Sequence)Asn1Object.FromByteArray(info.PrivateKey.GetDerEncoded());
    if (seq.Count != 9)
        throw new PemException("malformed sequence in RSA private key");

    var rsa = new RsaPrivateKeyStructure(seq);
    RsaPrivateCrtKeyParameters rsaparams = new RsaPrivateCrtKeyParameters(
        rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, rsa.Coefficient);

    x509.PrivateKey = DotNetUtilities.ToRSA(rsaparams);
    return x509;
}


public static AsymmetricKeyParameter GenerateCACertificate(string subjectName, int keyStrength = 2048)
{
    // Generating Random Numbers
    var randomGenerator = new CryptoApiRandomGenerator();
    var random = new SecureRandom(randomGenerator);

    // The Certificate Generator
    var certificateGenerator = new X509V3CertificateGenerator();

    // Serial Number
    var serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);
    certificateGenerator.SetSerialNumber(serialNumber);

    // Signature Algorithm
    const string signatureAlgorithm = "SHA256WithRSA";
    certificateGenerator.SetSignatureAlgorithm(signatureAlgorithm);

    // Issuer and Subject Name
    var subjectDN = new X509Name(subjectName);
    var issuerDN = subjectDN;
    certificateGenerator.SetIssuerDN(issuerDN);
    certificateGenerator.SetSubjectDN(subjectDN);

    // Valid For
    var notBefore = DateTime.UtcNow.Date;
    var notAfter = notBefore.AddYears(2);

    certificateGenerator.SetNotBefore(notBefore);
    certificateGenerator.SetNotAfter(notAfter);

    // Subject Public Key
    AsymmetricCipherKeyPair subjectKeyPair;
    var keyGenerationParameters = new KeyGenerationParameters(random, keyStrength);
    var keyPairGenerator = new RsaKeyPairGenerator();
    keyPairGenerator.Init(keyGenerationParameters);
    subjectKeyPair = keyPairGenerator.GenerateKeyPair();

    certificateGenerator.SetPublicKey(subjectKeyPair.Public);

    // Generating the Certificate
    var issuerKeyPair = subjectKeyPair;

    // Selfsign certificate
    var certificate = certificateGenerator.Generate(issuerKeyPair.Private, random);
    var x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate.GetEncoded());

    // Add CA certificate to Root store
    addCertToStore(cert, StoreName.Root, StoreLocation.CurrentUser);

    return issuerKeyPair.Private;
}
Run Code Online (Sandbox Code Playgroud)

并添加到商店(您的代码略有修改):

public static bool addCertToStore(System.Security.Cryptography.X509Certificates.X509Certificate2 cert, System.Security.Cryptography.X509Certificates.StoreName st, System.Security.Cryptography.X509Certificates.StoreLocation sl)
{
    bool bRet = false;

    try
    {
        X509Store store = new X509Store(st, sl);
        store.Open(OpenFlags.ReadWrite);
        store.Add(cert);

        store.Close();
    }
    catch
    {

    }

    return bRet;
}
Run Code Online (Sandbox Code Playgroud)

和用法:

var caPrivKey = GenerateCACertificate("CN=root ca");
var cert = GenerateSelfSignedCertificate("CN=127.0.01", "CN=root ca", caPrivKey);
addCertToStore(cert, StoreName.My, StoreLocation.CurrentUser);
Run Code Online (Sandbox Code Playgroud)

我没有在@wakeupneo评论之后编译这个示例代码.@wakeupneo您可能会稍微编辑代码并为每个证书添加适当的扩展名.


wak*_*neo 11

好的,感谢您的帮助,这里是工作代码:

private void button_Click(object sender, EventArgs e)
{
    AsymmetricKeyParameter myCAprivateKey = null;

    // Generate a root CA cert and obtain the privateKey
    X509Certificate2 MyRootCAcert = GenerateCACertificate("CN=MYTESTCA", ref myCAprivateKey);

    // Add CA certificate to store
    addCertToStore(MyRootCAcert, StoreName.Root, StoreLocation.LocalMachine);

    // Generate certificate based on the CA certificate privateKey
    X509Certificate2 MyCert = GenerateSelfSignedCertificate("CN=127.0.01", "CN=MYTESTCA", myCAprivateKey);

    // Add certificate to store
    addCertToStore(MyCert, StoreName.My, StoreLocation.LocalMachine);

    MessageBox.Show("Done!");
}


public static X509Certificate2 GenerateSelfSignedCertificate(string subjectName, string issuerName, AsymmetricKeyParameter issuerPrivKey)
{
    const int keyStrength = 2048;

    // Generating Random Numbers
    CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();
    SecureRandom random = new SecureRandom(randomGenerator);

    // The Certificate Generator
    X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator();

    // Serial Number
    BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);
    certificateGenerator.SetSerialNumber(serialNumber);

    // Signature Algorithm
    const string signatureAlgorithm = "SHA256WithRSA";
    certificateGenerator.SetSignatureAlgorithm(signatureAlgorithm);

    // Issuer and Subject Name
    X509Name subjectDN = new X509Name(subjectName);
    X509Name issuerDN = new X509Name(issuerName);
    certificateGenerator.SetIssuerDN(issuerDN);
    certificateGenerator.SetSubjectDN(subjectDN);

    // Valid For
    DateTime notBefore = DateTime.UtcNow.Date;
    DateTime notAfter = notBefore.AddYears(2);

    certificateGenerator.SetNotBefore(notBefore);
    certificateGenerator.SetNotAfter(notAfter);

    // Subject Public Key
    AsymmetricCipherKeyPair subjectKeyPair;
    var keyGenerationParameters = new KeyGenerationParameters(random, keyStrength);
    var keyPairGenerator = new RsaKeyPairGenerator();
    keyPairGenerator.Init(keyGenerationParameters);
    subjectKeyPair = keyPairGenerator.GenerateKeyPair();

    certificateGenerator.SetPublicKey(subjectKeyPair.Public);

    // Generating the Certificate
    AsymmetricCipherKeyPair issuerKeyPair = subjectKeyPair;

    // Selfsign certificate
    Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(issuerPrivKey, random);

    // Corresponding private key
    PrivateKeyInfo info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private);

    // Merge into X509Certificate2
    X509Certificate2 x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate.GetEncoded());

    Asn1Sequence seq = (Asn1Sequence)Asn1Object.FromByteArray(info.PrivateKey.GetDerEncoded());
    if (seq.Count != 9)
    {
        //throw new PemException("malformed sequence in RSA private key");
    }

    RsaPrivateKeyStructure rsa = new RsaPrivateKeyStructure(seq);
    RsaPrivateCrtKeyParameters rsaparams = new RsaPrivateCrtKeyParameters(
        rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, rsa.Coefficient);

    x509.PrivateKey = DotNetUtilities.ToRSA(rsaparams);
    return x509;

}

public static X509Certificate2 GenerateCACertificate(string subjectName, ref AsymmetricKeyParameter CaPrivateKey)
{
    const int keyStrength = 2048;

    // Generating Random Numbers
    CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();
    SecureRandom random = new SecureRandom(randomGenerator);

    // The Certificate Generator
    X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator();

    // Serial Number
    BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);
    certificateGenerator.SetSerialNumber(serialNumber);

    // Signature Algorithm
    const string signatureAlgorithm = "SHA256WithRSA";
    certificateGenerator.SetSignatureAlgorithm(signatureAlgorithm);

    // Issuer and Subject Name
    X509Name subjectDN = new X509Name(subjectName);
    X509Name issuerDN = subjectDN;
    certificateGenerator.SetIssuerDN(issuerDN);
    certificateGenerator.SetSubjectDN(subjectDN);

    // Valid For
    DateTime notBefore = DateTime.UtcNow.Date;
    DateTime notAfter = notBefore.AddYears(2);

    certificateGenerator.SetNotBefore(notBefore);
    certificateGenerator.SetNotAfter(notAfter);

    // Subject Public Key
    AsymmetricCipherKeyPair subjectKeyPair;
    KeyGenerationParameters keyGenerationParameters = new KeyGenerationParameters(random, keyStrength);
    RsaKeyPairGenerator keyPairGenerator = new RsaKeyPairGenerator();
    keyPairGenerator.Init(keyGenerationParameters);
    subjectKeyPair = keyPairGenerator.GenerateKeyPair();

    certificateGenerator.SetPublicKey(subjectKeyPair.Public);

    // Generating the Certificate
    AsymmetricCipherKeyPair issuerKeyPair = subjectKeyPair;

    // Selfsign certificate
    Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(issuerKeyPair.Private, random);
    X509Certificate2 x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate.GetEncoded());

    CaPrivateKey = issuerKeyPair.Private;

    return x509;
    //return issuerKeyPair.Private;
}

public static bool addCertToStore(System.Security.Cryptography.X509Certificates.X509Certificate2 cert, System.Security.Cryptography.X509Certificates.StoreName st, System.Security.Cryptography.X509Certificates.StoreLocation sl)
{
    bool bRet = false;

    try
    {
        X509Store store = new X509Store(st, sl);
        store.Open(OpenFlags.ReadWrite);
        store.Add(cert);

        store.Close();
    }
    catch
    {

    }
    return bRet;
}
Run Code Online (Sandbox Code Playgroud)


use*_*334 7

在整合多个帖子的更改后,我终于得到了这个代码!我希望这会为一些人节省很多时间!

static void Main(string[] args)
{
    AsymmetricKeyParameter caPrivateKey = null;
    var caCert = GenerateCACertificate("CN=MyROOTCA", ref caPrivateKey);
    addCertToStore(caCert, StoreName.Root, StoreLocation.LocalMachine);

    var clientCert = GenerateSelfSignedCertificate("CN=127.0.0.1", "CN=MyROOTCA", caPrivateKey);

    var p12 = clientCert.Export(X509ContentType.Pfx);

    addCertToStore(new X509Certificate2(p12, (string)null, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet), StoreName.My, StoreLocation.LocalMachine);
}

public static X509Certificate2 GenerateSelfSignedCertificate(string subjectName, string issuerName, AsymmetricKeyParameter issuerPrivKey)
{
    const int keyStrength = 2048;

    // Generating Random Numbers
    CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();
    SecureRandom random = new SecureRandom(randomGenerator);

    // The Certificate Generator
    X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator();

    // Serial Number
    BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);
    certificateGenerator.SetSerialNumber(serialNumber);

    // Signature Algorithm
    const string signatureAlgorithm = "SHA256WithRSA";
    certificateGenerator.SetSignatureAlgorithm(signatureAlgorithm);

    // Issuer and Subject Name
    X509Name subjectDN = new X509Name(subjectName);
    X509Name issuerDN = new X509Name(issuerName);
    certificateGenerator.SetIssuerDN(issuerDN);
    certificateGenerator.SetSubjectDN(subjectDN);

    // Valid For
    DateTime notBefore = DateTime.UtcNow.Date;
    DateTime notAfter = notBefore.AddYears(2);

    certificateGenerator.SetNotBefore(notBefore);
    certificateGenerator.SetNotAfter(notAfter);

    // Subject Public Key
    AsymmetricCipherKeyPair subjectKeyPair;
    var keyGenerationParameters = new KeyGenerationParameters(random, keyStrength);
    var keyPairGenerator = new RsaKeyPairGenerator();
    keyPairGenerator.Init(keyGenerationParameters);
    subjectKeyPair = keyPairGenerator.GenerateKeyPair();

    certificateGenerator.SetPublicKey(subjectKeyPair.Public);

    // Generating the Certificate
    AsymmetricCipherKeyPair issuerKeyPair = subjectKeyPair;

    // Selfsign certificate
    Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(issuerPrivKey, random);


    // Corresponding private key
    PrivateKeyInfo info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private);


    // Merge into X509Certificate2
    X509Certificate2 x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate.GetEncoded());

    Asn1Sequence seq = (Asn1Sequence)Asn1Object.FromByteArray(info.PrivateKey.GetDerEncoded());
    if (seq.Count != 9)
    {
        //throw new PemException("malformed sequence in RSA private key");
    }

    RsaPrivateKeyStructure rsa = new RsaPrivateKeyStructure(seq);
    RsaPrivateCrtKeyParameters rsaparams = new RsaPrivateCrtKeyParameters(
        rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, rsa.Coefficient);

    x509.PrivateKey = ToDotNetKey(rsaparams); //x509.PrivateKey = DotNetUtilities.ToRSA(rsaparams);
    return x509;
}

public static AsymmetricAlgorithm ToDotNetKey(RsaPrivateCrtKeyParameters privateKey)
{
    var cspParams = new CspParameters
    {
        KeyContainerName = Guid.NewGuid().ToString(),
        KeyNumber = (int)KeyNumber.Exchange,
        Flags = CspProviderFlags.UseMachineKeyStore
    };

    var rsaProvider = new RSACryptoServiceProvider(cspParams);
    var parameters = new RSAParameters
    {
        Modulus = privateKey.Modulus.ToByteArrayUnsigned(),
        P = privateKey.P.ToByteArrayUnsigned(),
        Q = privateKey.Q.ToByteArrayUnsigned(),
        DP = privateKey.DP.ToByteArrayUnsigned(),
        DQ = privateKey.DQ.ToByteArrayUnsigned(),
        InverseQ = privateKey.QInv.ToByteArrayUnsigned(),
        D = privateKey.Exponent.ToByteArrayUnsigned(),
        Exponent = privateKey.PublicExponent.ToByteArrayUnsigned()
    };

    rsaProvider.ImportParameters(parameters);
    return rsaProvider;
}

public static X509Certificate2 GenerateCACertificate(string subjectName, ref AsymmetricKeyParameter CaPrivateKey)
{
    const int keyStrength = 2048;

    // Generating Random Numbers
    CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();
    SecureRandom random = new SecureRandom(randomGenerator);

    // The Certificate Generator
    X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator();

    // Serial Number
    BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);
    certificateGenerator.SetSerialNumber(serialNumber);

    // Signature Algorithm
    const string signatureAlgorithm = "SHA256WithRSA";
    certificateGenerator.SetSignatureAlgorithm(signatureAlgorithm);

    // Issuer and Subject Name
    X509Name subjectDN = new X509Name(subjectName);
    X509Name issuerDN = subjectDN;
    certificateGenerator.SetIssuerDN(issuerDN);
    certificateGenerator.SetSubjectDN(subjectDN);

    // Valid For
    DateTime notBefore = DateTime.UtcNow.Date;
    DateTime notAfter = notBefore.AddYears(2);

    certificateGenerator.SetNotBefore(notBefore);
    certificateGenerator.SetNotAfter(notAfter);

    // Subject Public Key
    AsymmetricCipherKeyPair subjectKeyPair;
    KeyGenerationParameters keyGenerationParameters = new KeyGenerationParameters(random, keyStrength);
    RsaKeyPairGenerator keyPairGenerator = new RsaKeyPairGenerator();
    keyPairGenerator.Init(keyGenerationParameters);
    subjectKeyPair = keyPairGenerator.GenerateKeyPair();

    certificateGenerator.SetPublicKey(subjectKeyPair.Public);

    // Generating the Certificate
    AsymmetricCipherKeyPair issuerKeyPair = subjectKeyPair;

    // Selfsign certificate
    Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(issuerKeyPair.Private, random);
    X509Certificate2 x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate.GetEncoded());

    CaPrivateKey = issuerKeyPair.Private;

    return x509;
    //return issuerKeyPair.Private;
}

public static bool addCertToStore(System.Security.Cryptography.X509Certificates.X509Certificate2 cert, System.Security.Cryptography.X509Certificates.StoreName st, System.Security.Cryptography.X509Certificates.StoreLocation sl)
{
    bool bRet = false;

    try
    {
        X509Store store = new X509Store(st, sl);
        store.Open(OpenFlags.ReadWrite);
        store.Add(cert);

        store.Close();
    }
    catch
    {

    }

    return bRet;
}
Run Code Online (Sandbox Code Playgroud)


urs*_*rsa 6

我们在测试中使用以下代码

(a) NuGet 依赖:Bouncy Castle 1.7.0

<package id="BouncyCastle" version="1.7.0" targetFramework="net40" />
Run Code Online (Sandbox Code Playgroud)

(b) 自签名、中间和 CA 证书的生成器:

namespace Transport.Tests
{
    using System;
    using System.Security.Cryptography;
    using System.Security.Cryptography.X509Certificates;
    using Org.BouncyCastle.Asn1;
    using Org.BouncyCastle.Asn1.Pkcs;
    using Org.BouncyCastle.Asn1.X509;
    using Org.BouncyCastle.Crypto;
    using Org.BouncyCastle.Crypto.Generators;
    using Org.BouncyCastle.Crypto.Parameters;
    using Org.BouncyCastle.Crypto.Prng;
    using Org.BouncyCastle.Math;
    using Org.BouncyCastle.OpenSsl;
    using Org.BouncyCastle.Pkcs;
    using Org.BouncyCastle.Security;
    using Org.BouncyCastle.Utilities;
    using Org.BouncyCastle.X509;
    using Org.BouncyCastle.X509.Extension;

    public class X509Certificate2Builder
    {
        public string SubjectName
        { set { _subjectName = value; } }

        public string IssuerName
        { set { _issuerName = value; } }

        public AsymmetricAlgorithm IssuerPrivateKey
        { set { _issuerPrivateKey = value; } }

        public X509Certificate2 Issuer
        {
            set
            {
                _issuer = value;
                _issuerName = value.IssuerName.Name;
                if (value.HasPrivateKey)
                    _issuerPrivateKey = value.PrivateKey;
            }
        }

        public int? KeyStrength
        { set { _keyStrength = value ?? 2048; } }

        public DateTime? NotBefore
        { set { _notBefore = value; } }

        public DateTime? NotAfter
        { set { _notAfter = value; } }

        public bool Intermediate
        { set { _intermediate = value; } }

        private string _subjectName;
        private X509Certificate2 _issuer;
        private string _issuerName;
        private AsymmetricAlgorithm _issuerPrivateKey;
        private int _keyStrength = 2048;
        private DateTime? _notBefore;
        private DateTime? _notAfter;
        private bool _intermediate = true;

        public X509Certificate2 Build()
        {
            // Generating Random Numbers
            var randomGenerator = new CryptoApiRandomGenerator();
            var random = new SecureRandom(randomGenerator);

            // The Certificate Generator
            var certificateGenerator = new X509V3CertificateGenerator();

            // Serial Number
            var serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(long.MaxValue), random);
            certificateGenerator.SetSerialNumber(serialNumber);

            // Signature Algorithm
            certificateGenerator.SetSignatureAlgorithm("SHA256WithRSA");

            // Issuer and Subject Name
            certificateGenerator.SetIssuerDN(new X509Name(_issuerName ?? _subjectName));
            certificateGenerator.SetSubjectDN(new X509Name(_subjectName));

            // Authority Key Identifier
            if (_issuer != null)
            {
                var authorityKeyIdentifier = new AuthorityKeyIdentifierStructure(
                    DotNetUtilities.FromX509Certificate(_issuer));
                certificateGenerator.AddExtension(
                    X509Extensions.AuthorityKeyIdentifier.Id, false, authorityKeyIdentifier);
            }

            // Basic Constraints - certificate is allowed to be used as intermediate.
            certificateGenerator.AddExtension(
                X509Extensions.BasicConstraints.Id, true, new BasicConstraints(_intermediate));

            // Valid For
            certificateGenerator.SetNotBefore(_notBefore ?? DateTime.UtcNow.Date);
            certificateGenerator.SetNotAfter(_notAfter ?? DateTime.UtcNow.Date.AddYears(2));

            // Subject Public Key
            var keyGenerationParameters = new KeyGenerationParameters(random, _keyStrength);
            var keyPairGenerator = new RsaKeyPairGenerator();
            keyPairGenerator.Init(keyGenerationParameters);

            var subjectKeyPair = keyPairGenerator.GenerateKeyPair();
            var issuerKeyPair = _issuerPrivateKey == null
                ? subjectKeyPair
                : DotNetUtilities.GetKeyPair(_issuerPrivateKey);

            certificateGenerator.SetPublicKey(subjectKeyPair.Public);

            // selfsign certificate
            var certificate = certificateGenerator.Generate(issuerKeyPair.Private, random);

            // Merge into X509Certificate2
            return new X509Certificate2(certificate.GetEncoded())
            {
                PrivateKey = ConvertToRsaPrivateKey(subjectKeyPair)
            };
        }

        private static AsymmetricAlgorithm ConvertToRsaPrivateKey(AsymmetricCipherKeyPair keyPair)
        {
            var keyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(keyPair.Private);
            var seq = (Asn1Sequence) Asn1Object.FromByteArray(keyInfo.PrivateKey.GetDerEncoded());
            if (seq.Count != 9)
                throw new PemException("malformed sequence in RSA private key");

            var rsa = new RsaPrivateKeyStructure(seq);
            var rsaparams = new RsaPrivateCrtKeyParameters(
                rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1,
                rsa.Exponent2, rsa.Coefficient);

            return DotNetUtilities.ToRSA(rsaparams);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

(c) 用法示例:

var ca1 = new X509Certificate2Builder {SubjectName = "CN=Test CA1"}.Build();
var in1A = new X509Certificate2Builder { SubjectName = "CN=Intermediate 1A", Issuer = ca1}.Build();
var in1B = new X509Certificate2Builder { SubjectName = "CN=Intermediate 1B", Issuer = in1A}.Build();
var cert1 = new X509Certificate2Builder { SubjectName = "CN=Test 1", Issuer = in1B, Intermediate = false }.Build();
var cert1B = new X509Certificate2Builder { SubjectName = "CN=Test 1B", Issuer = cert1}.Build();

var ca2 = new X509Certificate2Builder { SubjectName = "CN=Test CA2"}.Build();
var cert2 = new X509Certificate2Builder { SubjectName = "CN=Test 2", Issuer = ca2, Intermediate = false}.Build();

var invalidCert1 = new X509Certificate2Builder
{
    SubjectName = "CN=Invalid 1",
    IssuerName = ca1.SubjectName.Name,
    IssuerPrivateKey = ca2.PrivateKey
}.Build();
var invalidCert2 = new X509Certificate2Builder
{
    SubjectName = "CN=Invalid 2",
    Issuer = ca2,
    NotBefore = DateTime.Now.AddDays(1)
}.Build();
Run Code Online (Sandbox Code Playgroud)


wak*_*neo 5

所以很长一段时间后,我完善了我的答案。我最初的任务是为 WCF 服务动态创建证书。

我的 Windows 服务应用程序有一个 WCF 服务,如果本地计算机上不存在相关证书,我想在运行时创建通道并创建相关证书。

上面的所有代码都是正确的方法,但是缺少一个。

您必须使用嵌入的可导出私钥创建证书。

请参阅此链接

这是生成私钥的代码段关键部分的重点:

var cspParams = new CspParameters
{
      KeyContainerName = Guid.NewGuid().ToString(),
      KeyNumber = (int)KeyNumber.Exchange,
      Flags = CspProviderFlags.UseMachineKeyStore
};
Run Code Online (Sandbox Code Playgroud)

如果在执行 netsh 命令时不这样做,则会收到错误 1312。例如,netsh 命令的:

netsh http add sslcert ipport=192.168.0.15:8081 certhash=?5424476237fc2785ed2d0fd620a9131d7c999f6f appid={02639d71-0935-35e8-9d1b-9dd1a2a34627}
Run Code Online (Sandbox Code Playgroud)