Generate a self-signed certificate on the fly

前端 未结 5 867
夕颜
夕颜 2020-11-27 11:27

I searched around, but I didn\'t find a clear example. I want to create a self-signed (self-)trusted certificate programmatically (C#), following these step

相关标签:
5条回答
  • 2020-11-27 11:29

    I edited the answer to do the root certificate first and then issue an end entity certificate.

    Here is some example of generating a self-signed certificate through Bouncy Castle:

    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;
    }
    

    And add to the store (your code slightly modified):

    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;
    }
    

    And usage:

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

    I have not compiled this example code after @wakeupneo comments. @wakeupneo, you might have to slightly edit the code and add proper extensions to each certificate.

    0 讨论(0)
  • Ok, thanks for the help. Here it is the working code:

    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;
    }
    
    0 讨论(0)
  • 2020-11-27 11:41

    So after a long time I refine my answer. My original task was to create a certificate on the fly for a WCF service.

    My Windows service application has a WCF service and I want to create the channel at runtime with the creation of the associated certificate if it's not present on the local machine.

    All the above code is the right way to do this, but there's one piece missing.

    You have to create a certificate with an embedded exportable private key.

    See this link.

    This is the focus on the critical part of the snippet to generate the private key:

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

    If you don't do this when you execute the netsh command, you get the error 1312. For example, of the netsh command:

    netsh http add sslcert ipport=192.168.0.15:8081 certhash=‎5424476237fc2785ed2d0fd620a9131d7c999f6f appid={02639d71-0935-35e8-9d1b-9dd1a2a34627}
    
    0 讨论(0)
  • 2020-11-27 11:45

    We are using the following code in our tests

    (a) NuGet dependency: Bouncy Castle 1.7.0

    <package id="BouncyCastle" version="1.7.0" targetFramework="net40" />
    

    (b) Builder for self-signed, intermediate and CA certificates:

    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);
            }
        }
    }
    

    (c) Example usage:

    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();
    
    0 讨论(0)
  • 2020-11-27 11:51

    After integrating changes from multiple posts, I finally got this code to work!

    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;
    }
    
    0 讨论(0)
提交回复
热议问题