Создавать самостоятельно подписанный сертификат на лету

Я искал вокруг, но не нашел ясного примера. Я хочу создать самоподписанный (самостоятельно) доверенный сертификат программным способом (c #) , следуя этому шагу:

STEP1: создайте корневой сертификат CA «на лету» и добавьте его в хранилище сертификатов в папке «Доверенные корневые центры сертификации»,

Я хочу сделать именно то, что делает этот инструмент командной строки:

makecert.exe -sk RootCA -sky подпись -pe -n CN = MY_CA -r -sr LocalMachine -ss Root MyCA.cer

STEP2: создайте сертификат на основе ранее созданного корневого сертификата CA и поместите его в хранилище сертификатов в папке «Личное»,

Я хочу сделать именно то, что делает этот инструмент командной строки:

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

Я хочу получить это:
введите описание изображения здесь

Я сделал это (см. Следующий код – STEP1), не знаю, как сделать STEP2, любая помощь будет оценена. Целевые машины – Windows XP / Seven. Я попробовал как чистый подход .net, так и библиотеку BouncyCastle .

//STEP1 mycerRoot=generateRootCertV1("MY_CA"); //tried also generateRootCertV2(BouncyCastle) addCertToStore(mycerRoot, StoreName.Root, StoreLocation.LocalMachine); //STEP2 mycer=generateCert("127.0.0.1",mycerRoot);//?????? <-- Something like that How to implement generateCert??? addCertToStore(mycer, StoreName.My, StoreLocation.LocalMachine); public static Org.BouncyCastle.X509.X509Certificate generateRootCertV2(string certName) { X509V1CertificateGenerator certGen = new X509V1CertificateGenerator(); X509Name CN = new X509Name("CN=" + certName); RsaKeyPairGenerator keypairgen = new RsaKeyPairGenerator(); keypairgen.Init(new KeyGenerationParameters(new SecureRandom(new CryptoApiRandomGenerator()), 1024)); AsymmetricCipherKeyPair keypair = keypairgen.GenerateKeyPair(); certGen.SetSerialNumber(BigInteger.ProbablePrime(120, new Random())); certGen.SetIssuerDN(CN); certGen.SetNotAfter(DateTime.MaxValue); certGen.SetNotBefore(DateTime.Now.Subtract(new TimeSpan(7, 0, 0, 0))); certGen.SetSubjectDN(CN); certGen.SetPublicKey(keypair.Public); certGen.SetSignatureAlgorithm("MD5WithRSA"); Org.BouncyCastle.X509.X509Certificate newCert = certGen.Generate(keypair.Private); return newCert; } public static X509Certificate2 GenerateRootCertV1(string HostNameOrIP_or_CertName) { X509Certificate2 cert = null; try { using (CryptContext ctx = new CryptContext()) { ctx.Open(); cert = ctx.CreateSelfSignedCertificate( new SelfSignedCertProperties { IsPrivateKeyExportable = true, KeyBitLength = 4096, Name = new X500DistinguishedName("cn=" + HostNameOrIP_or_CertName), ValidFrom = DateTime.Today.AddDays(-1), ValidTo = DateTime.Today.AddYears(20), }); } } catch (Exception ex) { } return cert; } public static bool addCertToStore(X509Certificate2 cert, StoreName st, StoreLocation sl) { bool bRet = false; try { X509Store store = new X509Store(st, sl); store.Open(OpenFlags.ReadWrite); if (cert != null) { byte[] pfx = cert.Export(X509ContentType.Pfx); cert = new X509Certificate2(pfx, (string)null, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet); if (!certExists(store, cert.SubjectName.Name)) { store.Add(cert); bRet = true; } } store.Close(); } catch { } return bRet; } 

Я отредактировал ответ, чтобы сначала выполнить root-сертификат, а затем выдал сертификат конечной сущности. Вот пример создания сертификата самоопределения через bouncy:

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

и добавить в магазин (ваш код слегка изменен):

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

и использование:

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

Я не компилировал этот пример кода после комментариев @wakeupneo. @wakeupneo вы можете слегка отредактировать код и добавить соответствующие расширения для каждого сертификата.

Хорошо, спасибо за помощь, вот рабочий код:

 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 cert to store addCertToStore(MyRootCAcert, StoreName.Root, StoreLocation.LocalMachine); //generate cert based on the CA cert privateKey X509Certificate2 MyCert = GenerateSelfSignedCertificate("CN=127.0.01", "CN=MYTESTCA", myCAprivateKey); //add cert 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); // correcponding 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; } 

После интеграции изменений с нескольких сообщений я, наконец, получил этот код для работы !. Надеюсь, это сэкономит много людей!

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

Мы используем следующий код в наших тестах

(a) Зависимость от Nuget: Bouncy Castle 1.7.0

  

(b) Builder для самоподписанных, промежуточных и сертификатов 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); } } } 

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

Поэтому после долгого времени я уточняю свой ответ. Моя первоначальная задача состояла в том, чтобы создать сертификат «на лету» для службы WCF.

В моем приложении службы Windows есть служба WCF, и я хочу создать канал во время выполнения с созданием соответствующего сертификата, если его нет на локальном компьютере.

Весь вышеприведенный код – это правильный способ сделать это, но отсутствует одна часть. Вам необходимо создать сертификат со встроенным закрытым закрытым ключом.

См. Эту ссылку

Это сосредоточено на критической части fragmentа для создания закрытого ключа:

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

Если вы этого не сделаете, когда вы выполняете команду netsh, вы получаете ошибку 1312. ie команды netsh:

netsh http add sslcert ipport = 192.168.0.15: 8081 certhash = 5424476237fc2785ed2d0fd620a9131d7c999f6f appid = {02639d71-0935-35e8-9d1b-9dd1a2a34627}

Interesting Posts

Поддержка локальной базы данных Sql для телефона Windows 7

Как создать временный файл с определенным расширением с .NET?

Как восстановить удаленный файл под Linux?

Создавать HTTP-запрос и получать ответ с помощью приложения консоли C #

Как запустить консольное приложение из Windows Service?

Не удается разрешить class MapActivity на Android

Используйте функцию в Powershell replace

Какова реальная причина не использовать бит EOF в качестве условия извлечения streamа?

Can ms dos список всех файлов и каталогов (включая скрытые)

Проблема распространения атрибутов Spirit Qi с одночленной структурой

MacOSX. Возможно ли иметь два интернет-соединения на одном компьютере?

Каков самый быстрый способ скопировать коллекцию в пределах одной базы данных?

Chrome не работает с подключением к удаленному рабочему столу

Внедрить IDispatch :: Invoke для вызова с помощью элемента управления WebBrowser

Как подписать DLL-файл .NET Assembly с сильным именем?

Давайте будем гением компьютера.