/// <summary> /// Creates a self signed application instance certificate. /// </summary> /// <param name="storeType">Type of certificate store (Directory) <see cref="CertificateStoreType"/>.</param> /// <param name="storePath">The store path (syntax depends on storeType).</param> /// <param name="password">The password to use to protect the certificate.</param> /// <param name="applicationUri">The application uri (created if not specified).</param> /// <param name="applicationName">Name of the application (optional if subjectName is specified).</param> /// <param name="subjectName">The subject used to create the certificate (optional if applicationName is specified).</param> /// <param name="domainNames">The domain names that can be used to access the server machine (defaults to local computer name if not specified).</param> /// <param name="keySize">Size of the key (1024, 2048 or 4096).</param> /// <param name="startTime">The start time.</param> /// <param name="lifetimeInMonths">The lifetime of the key in months.</param> /// <param name="hashSizeInBits">The hash size in bits.</param> /// <param name="isCA">if set to <c>true</c> then a CA certificate is created.</param> /// <param name="issuerCAKeyCert">The CA cert with the CA private key.</param> /// <returns>The certificate with a private key.</returns> public static X509Certificate2 CreateCertificate( string storeType, string storePath, string password, string applicationUri, string applicationName, string subjectName, IList <String> domainNames, ushort keySize, DateTime startTime, ushort lifetimeInMonths, ushort hashSizeInBits, bool isCA, X509Certificate2 issuerCAKeyCert) { if (issuerCAKeyCert != null) { if (!issuerCAKeyCert.HasPrivateKey) { throw new NotSupportedException("Cannot sign with a CA certificate without a private key."); } } // set default values. X509Name subjectDN = SetSuitableDefaults( ref applicationUri, ref applicationName, ref subjectName, ref domainNames, ref keySize, ref lifetimeInMonths, isCA); using (var cfrg = new CertificateFactoryRandomGenerator()) { // cert generators SecureRandom random = new SecureRandom(cfrg); X509V3CertificateGenerator cg = new X509V3CertificateGenerator(); // Serial Number BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random); cg.SetSerialNumber(serialNumber); X509Name issuerDN = null; if (issuerCAKeyCert != null) { issuerDN = new X509Name(true, issuerCAKeyCert.Subject.Replace("S=", "ST=")); } else { // self signed issuerDN = subjectDN; } cg.SetIssuerDN(issuerDN); cg.SetSubjectDN(subjectDN); // valid for cg.SetNotBefore(startTime); cg.SetNotAfter(startTime.AddMonths(lifetimeInMonths)); // Private/Public Key AsymmetricCipherKeyPair subjectKeyPair; var keyGenerationParameters = new KeyGenerationParameters(random, keySize); var keyPairGenerator = new RsaKeyPairGenerator(); keyPairGenerator.Init(keyGenerationParameters); subjectKeyPair = keyPairGenerator.GenerateKeyPair(); cg.SetPublicKey(subjectKeyPair.Public); // add extensions // Subject key identifier cg.AddExtension(X509Extensions.SubjectKeyIdentifier.Id, false, new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(subjectKeyPair.Public))); // Basic constraints cg.AddExtension(X509Extensions.BasicConstraints.Id, true, new BasicConstraints(isCA)); // Authority Key identifier var issuerKeyPair = subjectKeyPair; var issuerSerialNumber = serialNumber; cg.AddExtension(X509Extensions.AuthorityKeyIdentifier.Id, false, new AuthorityKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(subjectKeyPair.Public), new GeneralNames(new GeneralName(issuerDN)), issuerSerialNumber)); if (!isCA) { // Key usage cg.AddExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.DataEncipherment | KeyUsage.DigitalSignature | KeyUsage.NonRepudiation | KeyUsage.KeyCertSign | KeyUsage.KeyEncipherment)); // Extended Key usage cg.AddExtension(X509Extensions.ExtendedKeyUsage, true, new ExtendedKeyUsage(new List <DerObjectIdentifier>() { new DerObjectIdentifier("1.3.6.1.5.5.7.3.1"), // server auth new DerObjectIdentifier("1.3.6.1.5.5.7.3.2"), // client auth })); // subject alternate name cg.AddExtension(X509Extensions.SubjectAlternativeName, false, new GeneralNames(new GeneralName[] { new GeneralName(GeneralName.UniformResourceIdentifier, applicationUri), new GeneralName(GeneralName.DnsName, domainNames[0]) })); } else { // Key usage CA cg.AddExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.CrlSign | KeyUsage.DigitalSignature | KeyUsage.KeyCertSign)); } // sign certificate AsymmetricKeyParameter privateKey = null; if (issuerCAKeyCert != null) { using (RSA rsa = issuerCAKeyCert.GetRSAPrivateKey()) { RSAParameters rsaParams = rsa.ExportParameters(true); RsaPrivateCrtKeyParameters keyParams = new RsaPrivateCrtKeyParameters( new BigInteger(1, rsaParams.Modulus), new BigInteger(1, rsaParams.Exponent), new BigInteger(1, rsaParams.D), new BigInteger(1, rsaParams.P), new BigInteger(1, rsaParams.Q), new BigInteger(1, rsaParams.DP), new BigInteger(1, rsaParams.DQ), new BigInteger(1, rsaParams.InverseQ)); privateKey = keyParams; } } else { privateKey = subjectKeyPair.Private; } ISignatureFactory signatureFactory = new Asn1SignatureFactory((hashSizeInBits < 256) ? "SHA1WITHRSA" : "SHA256WITHRSA", privateKey, random); Org.BouncyCastle.X509.X509Certificate x509 = cg.Generate(signatureFactory); // create pkcs12 store for cert and private key X509Certificate2 certificate = null; using (MemoryStream pfxData = new MemoryStream()) { Pkcs12Store pkcsStore = new Pkcs12StoreBuilder().Build(); X509CertificateEntry[] chain = new X509CertificateEntry[1]; string passcode = Guid.NewGuid().ToString(); chain[0] = new X509CertificateEntry(x509); pkcsStore.SetKeyEntry(applicationName, new AsymmetricKeyEntry(subjectKeyPair.Private), chain); pkcsStore.Save(pfxData, passcode.ToCharArray(), random); // merge into X509Certificate2 certificate = CreateCertificateFromPKCS12(pfxData.ToArray(), passcode); } Utils.Trace(Utils.TraceMasks.Security, "Created new certificate: {0}", certificate.Thumbprint); // add cert to the store. if (!String.IsNullOrEmpty(storePath)) { ICertificateStore store = null; if (storeType == CertificateStoreType.X509Store) { store = new X509CertificateStore(); } else if (storeType == CertificateStoreType.Directory) { store = new DirectoryCertificateStore(); } else { throw new ArgumentException("Invalid store type"); } store.Open(storePath); store.Add(certificate, password); store.Close(); store.Dispose(); } // note: this cert has a private key! return(certificate); } }
private static X509Certificate2 GenerateSelfSignedCertificate(string subjectName, string issuerName, AsymmetricKeyParameter issuerPrivKey) { const 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); // self-sign certificate var certificate = certificateGenerator.Generate(issuerPrivKey, random); // corresponding private key var info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private); // merge into X509Certificate2 var x509 = new 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 = RsaPrivateKeyStructure.GetInstance(seq); var rsaparams = new RsaPrivateCrtKeyParameters( rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, rsa.Coefficient); x509.PrivateKey = ToDotNetKey(rsaparams); return(x509); }
/// <summary> /// Static method used to create a certificate and return as a .net object /// </summary> public static X509Certificate2 Create(string name, DateTime start, DateTime end, string userPassword, bool addtoStore = false) { // generate a key pair using RSA var generator = new RsaKeyPairGenerator(); // keys have to be a minimum of 2048 bits for Azure generator.Init(new KeyGenerationParameters(new SecureRandom(new CryptoApiRandomGenerator()), 2048)); AsymmetricCipherKeyPair cerKp = generator.GenerateKeyPair(); // get a copy of the private key AsymmetricKeyParameter privateKey = cerKp.Private; // create the CN using the name passed in and create a unique serial number for the cert var certName = new X509Name("CN=" + name); BigInteger serialNo = BigInteger.ProbablePrime(120, new Random()); // start the generator and set CN/DN and serial number and valid period var x509Generator = new X509V3CertificateGenerator(); x509Generator.SetSerialNumber(serialNo); x509Generator.SetSubjectDN(certName); x509Generator.SetIssuerDN(certName); x509Generator.SetNotBefore(start); x509Generator.SetNotAfter(end); // add the server authentication key usage var keyUsage = new KeyUsage(KeyUsage.KeyEncipherment); x509Generator.AddExtension(X509Extensions.KeyUsage, false, keyUsage.ToAsn1Object()); var extendedKeyUsage = new ExtendedKeyUsage(new[] { KeyPurposeID.IdKPServerAuth }); x509Generator.AddExtension(X509Extensions.ExtendedKeyUsage, true, extendedKeyUsage.ToAsn1Object()); // algorithm can only be SHA1 ?? x509Generator.SetSignatureAlgorithm("sha1WithRSA"); // Set the key pair x509Generator.SetPublicKey(cerKp.Public); X509Certificate certificate = x509Generator.Generate(cerKp.Private); // export the certificate bytes byte[] certStream = DotNetUtilities.ToX509Certificate(certificate).Export(X509ContentType.Pkcs12, userPassword); // build the key parameter and the certificate entry var keyEntry = new AsymmetricKeyEntry(privateKey); var entry = new X509CertificateEntry(certificate); // build the PKCS#12 store to encapsulate the certificate var builder = new Pkcs12StoreBuilder(); builder.SetUseDerEncoding(true); builder.SetCertAlgorithm(PkcsObjectIdentifiers.Sha1WithRsaEncryption); builder.SetKeyAlgorithm(PkcsObjectIdentifiers.Sha1WithRsaEncryption); builder.Build(); // create a memorystream to hold the output var stream = new MemoryStream(2000); // create the individual store and set two entries for cert and key var store = new Pkcs12Store(); store.SetCertificateEntry("Elastacloud Test Certificate", entry); store.SetKeyEntry("Elastacloud Test Certificate", keyEntry, new[] { entry }); store.Save(stream, userPassword.ToCharArray(), new SecureRandom()); // Create the equivalent C# representation var cert = new X509Certificate2(stream.GetBuffer(), userPassword, X509KeyStorageFlags.Exportable); // if specified then this add this certificate to the store if (addtoStore) { AddToMyStore(cert); } return(cert); }
public void TestCreationECDSA() { BigInteger ECParraGX = new BigInteger(Base64.Decode("D/qWPNyogWzMM7hkK+35BcPTWFc9Pyf7vTs8uaqv")); BigInteger ECParraGY = new BigInteger(Base64.Decode("AhQXGxb1olGRv6s1LPRfuatMF+cx3ZTGgzSE/Q5R")); BigInteger ECParraH = new BigInteger(Base64.Decode("AQ==")); BigInteger ECParraN = new BigInteger(Base64.Decode("f///////////////f///nl6an12QcfvRUiaIkJ0L")); BigInteger ECPubQX = new BigInteger(Base64.Decode("HWWi17Yb+Bm3PYr/DMjLOYNFhyOwX1QY7ZvqqM+l")); BigInteger ECPubQY = new BigInteger(Base64.Decode("JrlJfxu3WGhqwtL/55BOs/wsUeiDFsvXcGhB8DGx")); BigInteger ECPrivD = new BigInteger(Base64.Decode("GYQmd/NF1B+He1iMkWt3by2Az6Eu07t0ynJ4YCAo")); X9ECParameters x9 = ECNamedCurveTable.GetByName("prime239v1"); ECCurve curve = x9.Curve; ECDomainParameters ecDomain = new ECDomainParameters(curve, curve.ValidatePoint(ECParraGX, ECParraGY), ECParraN, ECParraH); ECPublicKeyParameters ecPub = new ECPublicKeyParameters("ECDSA", curve.ValidatePoint(ECPubQX, ECPubQY), ecDomain); ECPrivateKeyParameters ecPriv = new ECPrivateKeyParameters("ECDSA", ECPrivD, ecDomain); IDictionary attrs = new Hashtable(); attrs[X509Name.C] = "AU"; attrs[X509Name.O] = "The Legion of the Bouncy Castle"; attrs[X509Name.L] = "Melbourne"; attrs[X509Name.ST] = "Victoria"; attrs[X509Name.E] = "*****@*****.**"; IList ord = new ArrayList(); ord.Add(X509Name.C); ord.Add(X509Name.O); ord.Add(X509Name.L); ord.Add(X509Name.ST); ord.Add(X509Name.E); IList values = new ArrayList(); values.Add("AU"); values.Add("The Legion of the Bouncy Castle"); values.Add("Melbourne"); values.Add("Victoria"); values.Add("*****@*****.**"); X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.SetSerialNumber(BigInteger.One); certGen.SetIssuerDN(new X509Name(ord, attrs)); certGen.SetNotBefore(DateTime.Today.Subtract(new TimeSpan(1, 0, 0, 0))); certGen.SetNotAfter(DateTime.Today.AddDays(1)); certGen.SetSubjectDN(new X509Name(ord, attrs)); certGen.SetPublicKey(ecPub); certGen.SetSignatureAlgorithm("SHA1WITHECDSA"); certGen.AddExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(false)); X509Certificate cert = certGen.Generate(ecPriv); // Assert.IsTrue((cert.IsValidNow && cert.Verify(ecPub)), "Certificate failed to be valid (ECDSA)"); cert.CheckValidity(); cert.Verify(ecPub); ISet extOidSet = cert.GetCriticalExtensionOids(); if (extOidSet.Count != 1) { Fail("wrong number of oids"); } //if (dummySet != null) //{ // foreach (string key in dummySet) // { // Console.WriteLine("\t{0}:\t{1}", key); // } //} //Console.WriteLine(); //dummySet = cert.GetNonCriticalExtensionOids(); //if (dummySet != null) //{ // foreach (string key in dummySet) // { // Console.WriteLine("\t{0}:\t{1}", key); // } //} //Console.WriteLine(); }
/// <summary> /// Creates the certificate based on the subject name /// </summary> /// <param name="certificate">The certificate object with custom values for the certificate</param> /// <returns></returns> public static bool GeneratePfx(CertificateAttributes certificate) { var isCertificateCreated = false; try { var keyPairGenerator = new RsaKeyPairGenerator(); keyPairGenerator.Init(new KeyGenerationParameters(new SecureRandom(new CryptoApiRandomGenerator()), 1024)); var kp = keyPairGenerator.GenerateKeyPair(); var signatureFactory = new Asn1SignatureFactory(certificate.Algorithm.GetDescription(), kp.Private); var gen = new X509V3CertificateGenerator(); var certName = new X509Name("CN=" + certificate.SubjectName); var serialNo = BigInteger.ProbablePrime(120, new Random()); //sets the serial no for the certificate : add a custom serial no if you have one gen.SetSerialNumber(serialNo); //set the subject name : can be custom here gen.SetSubjectDN(certName); //sets the issuer name gen.SetIssuerDN(certName); gen.SetNotAfter(DateTime.Now.AddYears(100)); gen.SetNotBefore(DateTime.Now.Subtract(new TimeSpan(7, 0, 0, 0))); //set the public key for the certificate gen.SetPublicKey(kp.Public); gen.AddExtension( X509Extensions.AuthorityKeyIdentifier.Id, false, new AuthorityKeyIdentifier( SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(kp.Public), new GeneralNames(new GeneralName(certName)), serialNo)); gen.AddExtension( X509Extensions.ExtendedKeyUsage.Id, false, new ExtendedKeyUsage(new List <object> { new DerObjectIdentifier("1.3.6.1.5.5.7.3.1") })); var newCert = gen.Generate(signatureFactory); var createdCertificate = DotNetUtilities.ToX509Certificate(newCert); var byteArray = createdCertificate.Export(X509ContentType.Pkcs12, certificate.Password); var byteArray1 = createdCertificate.Export(X509ContentType.Cert, certificate.Password); //Save the pfx file here Helper.WriteAllBytes("C:\\certs\\" + certificate.SubjectName + ".pfx", byteArray); //save the cert here if (certificate.SaveCerFile) { Helper.WriteAllBytes("C:\\certs\\" + certificate.SubjectName + ".cer", byteArray1); } isCertificateCreated = true; } catch (Exception exception) { var logger = new Logger.FileLogger(); logger.Log(exception); } return(isCertificateCreated); }
/// <summary> /// Generates the certificate. /// </summary> /// <param name="subjectName">Name of the subject.</param> /// <param name="issuerName">Name of the issuer.</param> /// <param name="validFrom">The valid from.</param> /// <param name="validTo">The valid to.</param> /// <param name="subjectKeyPair">The key pair.</param> /// <param name="signatureAlgorithm">The signature algorithm.</param> /// <param name="issuerPrivateKey">The issuer private key.</param> /// <param name="hostName">The host name</param> /// <returns>X509Certificate2 instance.</returns> /// <exception cref="PemException">Malformed sequence in RSA private key</exception> private static X509Certificate2 generateCertificate(string?hostName, string subjectName, string issuerName, DateTime validFrom, DateTime validTo, AsymmetricCipherKeyPair subjectKeyPair, string signatureAlgorithm = "SHA256WithRSA", AsymmetricKeyParameter?issuerPrivateKey = null) { // Generating Random Numbers var randomGenerator = new CryptoApiRandomGenerator(); var secureRandom = new SecureRandom(randomGenerator); // The Certificate Generator var certificateGenerator = new X509V3CertificateGenerator(); // Serial Number var serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(long.MaxValue), secureRandom); certificateGenerator.SetSerialNumber(serialNumber); // Issuer and Subject Name var subjectDn = new X509Name(subjectName); var issuerDn = new X509Name(issuerName); certificateGenerator.SetIssuerDN(issuerDn); certificateGenerator.SetSubjectDN(subjectDn); certificateGenerator.SetNotBefore(validFrom); certificateGenerator.SetNotAfter(validTo); if (hostName != null) { // add subject alternative names var nameType = GeneralName.DnsName; if (IPAddress.TryParse(hostName, out _)) { nameType = GeneralName.IPAddress; } var subjectAlternativeNames = new Asn1Encodable[] { new GeneralName(nameType, hostName) }; var subjectAlternativeNamesExtension = new DerSequence(subjectAlternativeNames); certificateGenerator.AddExtension(X509Extensions.SubjectAlternativeName.Id, false, subjectAlternativeNamesExtension); } // Subject Public Key certificateGenerator.SetPublicKey(subjectKeyPair.Public); // Set certificate intended purposes to only Server Authentication certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage.Id, false, new ExtendedKeyUsage(KeyPurposeID.IdKPServerAuth)); if (issuerPrivateKey == null) { certificateGenerator.AddExtension(X509Extensions.BasicConstraints.Id, true, new BasicConstraints(true)); } var signatureFactory = new Asn1SignatureFactory(signatureAlgorithm, issuerPrivateKey ?? subjectKeyPair.Private, secureRandom); // Self-sign the certificate var certificate = certificateGenerator.Generate(signatureFactory); // Corresponding private key var privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private); var seq = (Asn1Sequence)Asn1Object.FromByteArray(privateKeyInfo.ParsePrivateKey().GetDerEncoded()); if (seq.Count != 9) { throw new PemException("Malformed sequence in RSA private key"); } var rsa = RsaPrivateKeyStructure.GetInstance(seq); var rsaparams = new RsaPrivateCrtKeyParameters(rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, rsa.Coefficient); // Set private key onto certificate instance var x509Certificate = withPrivateKey(certificate, rsaparams); if (!doNotSetFriendlyName) { try { x509Certificate.FriendlyName = ProxyConstants.CNRemoverRegex.Replace(subjectName, string.Empty); } catch (PlatformNotSupportedException) { doNotSetFriendlyName = true; } } return(x509Certificate); }
/// <inheritdoc/> public async Task <(X509Certificate?Certificate, RsaKeyParameters?Key)> GetLocalCertificateAsync(ApplicationDescription applicationDescription, ILogger?logger = null, CancellationToken token = default) { if (applicationDescription == null) { throw new ArgumentNullException(nameof(applicationDescription)); } string?applicationUri = applicationDescription.ApplicationUri; if (string.IsNullOrEmpty(applicationUri)) { throw new ArgumentOutOfRangeException(nameof(applicationDescription), "Expecting ApplicationUri in the form of 'http://{hostname}/{appname}' -or- 'urn:{hostname}:{appname}'."); } string?subjectName = null; string?hostName = null; string?appName = null; UriBuilder appUri = new UriBuilder(applicationUri); if (appUri.Scheme == "http" && !string.IsNullOrEmpty(appUri.Host)) { var path = appUri.Path.Trim('/'); if (!string.IsNullOrEmpty(path)) { hostName = appUri.Host; appName = path; subjectName = $"CN={appName},DC={hostName}"; } } if (appUri.Scheme == "urn") { var parts = appUri.Path.Split(new[] { ':' }, 2); if (parts.Length == 2) { hostName = parts[0]; appName = parts[1]; subjectName = $"CN={appName},DC={hostName}"; } } if (subjectName == null) { throw new ArgumentOutOfRangeException(nameof(applicationDescription), "Expecting ApplicationUri in the form of 'http://{hostname}/{appname}' -or- 'urn:{hostname}:{appname}'."); } var crt = default(X509Certificate); var key = default(RsaKeyParameters); // Build 'own/certs' certificate store. var ownCerts = new Org.BouncyCastle.Utilities.Collections.HashSet(); var ownCertsInfo = new DirectoryInfo(Path.Combine(_pkiPath, "own", "certs")); if (ownCertsInfo.Exists) { foreach (var info in ownCertsInfo.EnumerateFiles()) { using (var crtStream = info.OpenRead()) { var c = _certParser.ReadCertificate(crtStream); if (c != null) { ownCerts.Add(c); } } } } IX509Store ownCertStore = X509StoreFactory.Create("Certificate/Collection", new X509CollectionStoreParameters(ownCerts)); // Select the newest certificate that matches by subject name. var selector = new X509CertStoreSelector() { Subject = new X509Name(subjectName) }; crt = ownCertStore.GetMatches(selector).OfType <X509Certificate>().OrderBy(c => c.NotBefore).LastOrDefault(); if (crt != null) { // If certificate found, verify alt-name, and retrieve private key. var asn1OctetString = crt.GetExtensionValue(X509Extensions.SubjectAlternativeName); if (asn1OctetString != null) { var asn1Object = X509ExtensionUtilities.FromExtensionValue(asn1OctetString); GeneralNames gns = GeneralNames.GetInstance(asn1Object); if (gns.GetNames().Any(n => n.TagNo == GeneralName.UniformResourceIdentifier && n.Name.ToString() == applicationUri)) { var ki = new FileInfo(Path.Combine(_pkiPath, "own", "private", $"{crt.SerialNumber}.key")); if (ki.Exists) { using (var keyStream = new StreamReader(ki.OpenRead())) { var keyReader = new PemReader(keyStream); var keyPair = keyReader.ReadObject() as AsymmetricCipherKeyPair; if (keyPair != null) { key = keyPair.Private as RsaKeyParameters; } } } } } } // If certificate and key are found, return to caller. if (crt != null && key != null) { logger?.LogTrace($"Found certificate with subject alt name '{applicationUri}'."); return(crt, key); } if (!CreateLocalCertificateIfNotExist) { return(null, null); } // Create new certificate var subjectDN = new X509Name(subjectName); // Create a keypair. var kp = await Task.Run <AsymmetricCipherKeyPair>(() => { RsaKeyPairGenerator kg = new RsaKeyPairGenerator(); kg.Init(new KeyGenerationParameters(_rng, 2048)); return(kg.GenerateKeyPair()); }); key = kp.Private as RsaPrivateCrtKeyParameters; // Create a certificate. X509V3CertificateGenerator cg = new X509V3CertificateGenerator(); var subjectSN = BigInteger.ProbablePrime(120, _rng); cg.SetSerialNumber(subjectSN); cg.SetSubjectDN(subjectDN); cg.SetIssuerDN(subjectDN); cg.SetNotBefore(DateTime.Now.Date.ToUniversalTime()); cg.SetNotAfter(DateTime.Now.Date.ToUniversalTime().AddYears(25)); cg.SetPublicKey(kp.Public); cg.AddExtension( X509Extensions.BasicConstraints.Id, true, new BasicConstraints(false)); cg.AddExtension( X509Extensions.SubjectKeyIdentifier.Id, false, new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(kp.Public))); cg.AddExtension( X509Extensions.AuthorityKeyIdentifier.Id, false, new AuthorityKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(kp.Public), new GeneralNames(new GeneralName(subjectDN)), subjectSN)); cg.AddExtension( X509Extensions.SubjectAlternativeName, false, new GeneralNames(new[] { new GeneralName(GeneralName.UniformResourceIdentifier, applicationUri), new GeneralName(GeneralName.DnsName, hostName) })); cg.AddExtension( X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.DataEncipherment | KeyUsage.DigitalSignature | KeyUsage.NonRepudiation | KeyUsage.KeyCertSign | KeyUsage.KeyEncipherment)); cg.AddExtension( X509Extensions.ExtendedKeyUsage, true, new ExtendedKeyUsage(KeyPurposeID.IdKPClientAuth, KeyPurposeID.IdKPServerAuth)); crt = cg.Generate(new Asn1SignatureFactory("SHA256WITHRSA", key, _rng)); logger?.LogTrace($"Created certificate with subject alt name '{applicationUri}'."); var keyInfo = new FileInfo(Path.Combine(_pkiPath, "own", "private", $"{crt.SerialNumber}.key")); if (!keyInfo.Directory.Exists) { Directory.CreateDirectory(keyInfo.DirectoryName); } else if (keyInfo.Exists) { keyInfo.Delete(); } using (var keystream = new StreamWriter(keyInfo.OpenWrite())) { var pemwriter = new PemWriter(keystream); pemwriter.WriteObject(key); } var crtInfo = new FileInfo(Path.Combine(_pkiPath, "own", "certs", $"{crt.SerialNumber}.crt")); if (!crtInfo.Directory.Exists) { Directory.CreateDirectory(crtInfo.DirectoryName); } else if (crtInfo.Exists) { crtInfo.Delete(); } using (var crtstream = new StreamWriter(crtInfo.OpenWrite())) { var pemwriter = new PemWriter(crtstream); pemwriter.WriteObject(crt); } return(crt, key); }
/// <summary> /// 生成X509 V3证书 /// </summary> /// <param name="certPath">Cert证书路径</param> /// <param name="endDate">证书失效时间</param> /// <param name="keySize">密钥长度</param> /// <param name="password">证书密码</param> /// <param name="signatureAlgorithm">设置将用于签署此证书的签名算法</param> /// <param name="issuer">设置此证书颁发者的DN</param> /// <param name="subject">设置此证书使用者的DN</param> /// <param name="pfxPath">Pfx证书路径</param> /// <param name="friendlyName">设置证书友好名称(可选)</param> /// <param name="startDate">证书生效时间</param> /// <param name="algorithm">加密算法</param> public static void X509V3(string algorithm, int keySize, string password, string signatureAlgorithm, DateTime startDate, DateTime endDate, X509Name issuer, X509Name subject, string certPath, string pfxPath, string friendlyName = "") { //generate Random Numbers CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator(); SecureRandom random = new SecureRandom(randomGenerator); var keyGenerator = GeneratorUtilities.GetKeyPairGenerator(algorithm); keyGenerator.Init(new KeyGenerationParameters(new SecureRandom(), keySize)); var keyPair = keyGenerator.GenerateKeyPair(); var v3CertGen = new X509V3CertificateGenerator(); var serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(long.MaxValue), random); v3CertGen.SetSerialNumber(serialNumber); //设置证书的序列号 v3CertGen.SetIssuerDN(issuer); //设置颁发者信息 v3CertGen.SetSubjectDN(subject); //设置使用者信息 v3CertGen.SetNotBefore(startDate); //设置证书的生效日期 v3CertGen.SetNotAfter(endDate); //设置证书失效的日期 v3CertGen.SetPublicKey(keyPair.Public); //设置此证书的公钥 ISignatureFactory sigFact = new Asn1SignatureFactory(signatureAlgorithm, keyPair.Private); //签名算法&设置此证书的私钥 var spki = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keyPair.Public); //设置一些扩展字段 //基本约束 v3CertGen.AddExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(true)); //使用者密钥标识符 v3CertGen.AddExtension(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifier(spki)); //授权密钥标识符 v3CertGen.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifier(spki)); var x509Certificate = v3CertGen.Generate(sigFact); //生成证书 x509Certificate.CheckValidity(); //检查当前日期是否在证书的有效期内 x509Certificate.Verify(keyPair.Public); //使用公钥验证证书的签名 var certificate2 = new X509Certificate2(DotNetUtilities.ToX509Certificate(x509Certificate)) { FriendlyName = friendlyName, //设置友好名称 }; //cer公钥文件 var bytes = certificate2.Export(X509ContentType.Cert); using (var fs = new FileStream(certPath, FileMode.Create)) { fs.Write(bytes, 0, bytes.Length); } //pfx证书,包含公钥私钥 //CopyWithPrivateKey netstandard2.1支持 certificate2 = certificate2.CopyWithPrivateKey(DotNetUtilities.ToRSA((RsaPrivateCrtKeyParameters)keyPair.Private)); var bytes2 = certificate2.Export(X509ContentType.Pfx, password); using (var fs = new FileStream(pfxPath, FileMode.Create)) { fs.Write(bytes2, 0, bytes2.Length); } //如果使用 netstandard2.0 请使用下面的代码 #if NETSTANDARD2_0 var certEntry = new X509CertificateEntry(x509Certificate); var store = new Pkcs12StoreBuilder().Build(); store.SetCertificateEntry(friendlyName, certEntry); //设置证书 var chain = new X509CertificateEntry[1]; chain[0] = certEntry; store.SetKeyEntry(friendlyName, new AsymmetricKeyEntry(keyPair.Private), chain); //设置私钥 using (var fs = File.Create(pfxPath)) { store.Save(fs, password.ToCharArray(), new SecureRandom()); //保存 } #endif }
//[Obsolete("Use CreateSelfSignedTlsCert instead.")] public static X509Certificate2 CreateSelfSignedCert(string subjectName, string issuerName, AsymmetricKeyParameter privateKey) { const int keyStrength = DEFAULT_KEY_SIZE; if (privateKey == null) { privateKey = CreatePrivateKeyResource(issuerName); } var issuerPrivKey = privateKey; // Generating Random Numbers var randomGenerator = new CryptoApiRandomGenerator(); var random = new SecureRandom(randomGenerator); ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA256WITHRSA", issuerPrivKey, random); // The Certificate Generator var certificateGenerator = new X509V3CertificateGenerator(); certificateGenerator.AddExtension(X509Extensions.SubjectAlternativeName, false, new GeneralNames(new GeneralName[] { new GeneralName(GeneralName.DnsName, "localhost"), new GeneralName(GeneralName.DnsName, "127.0.0.1") })); certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage, true, new ExtendedKeyUsage(new List <DerObjectIdentifier>() { new DerObjectIdentifier("1.3.6.1.5.5.7.3.1") })); // Serial Number var serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random); certificateGenerator.SetSerialNumber(serialNumber); // 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(70); certificateGenerator.SetNotBefore(notBefore); certificateGenerator.SetNotAfter(notAfter); // Subject Public Key var keyGenerationParameters = new KeyGenerationParameters(random, keyStrength); var keyPairGenerator = new RsaKeyPairGenerator(); keyPairGenerator.Init(keyGenerationParameters); var subjectKeyPair = keyPairGenerator.GenerateKeyPair(); certificateGenerator.SetPublicKey(subjectKeyPair.Public); // self sign certificate var certificate = certificateGenerator.Generate(signatureFactory); // Originally pre-processor defines were used to try and pick the supported way to get from a Bouncy Castle // certificate and private key to a .NET certificate. The problem is that setting the private key on a .NET // X509 certificate is possible in .NET Framework but NOT in .NET Core. To complicate matters even further // the workaround in the CovertBouncyCert method of saving a cert + pvt key to a .pfx stream and then // reloading does not work on macOS or Unity (and possibly elsewhere) due to .pfx serialisation not being // compatible. This is the exception from Unity: // // Mono.Security.ASN1..ctor (System.Byte[] data) (at <6a66fe237d4242c9924192d3c28dd540>:0) // Mono.Security.X509.X509Certificate.Parse(System.Byte[] data)(at < 6a66fe237d4242c9924192d3c28dd540 >:0) // // Summary: // .NET Framework (including Mono on Linux, macOS and WSL) // - Set x509.PrivateKey works. // .NET Standard: // - Set x509.PrivateKey for a .NET Framework application. // - Set x509.PrivateKey for a .NET Core application FAILS. // .NET Core: // - Set x509.PrivateKey for a .NET Core application FAILS. // - PFX serialisation works on Windows. // - PFX serialisation works on WSL and Linux. // - PFX serialisation FAILS on macOS. // // For same issue see https://github.com/dotnet/runtime/issues/23635. // For fix in net5 see https://github.com/dotnet/corefx/pull/42226. try { // corresponding private key var info = Org.BouncyCastle.Pkcs.PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private); // merge into X509Certificate2 var x509 = new X509Certificate2(certificate.GetEncoded()); var seq = (Asn1Sequence)Asn1Object.FromByteArray(info.ParsePrivateKey().GetDerEncoded()); if (seq.Count != 9) { throw new Org.BouncyCastle.OpenSsl.PemException("malformed sequence in RSA private key"); } var rsa = RsaPrivateKeyStructure.GetInstance(seq); //new RsaPrivateKeyStructure(seq); var rsaparams = new RsaPrivateCrtKeyParameters( rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, rsa.Coefficient); x509.PrivateKey = ToRSA(rsaparams); return(x509); } catch { return(ConvertBouncyCert(certificate, subjectKeyPair)); } }
/// <summary> /// Creates a cert with the connectionstring (token) and stores it in the given cert store. /// </summary> public async static Task WriteAsync(string name, string connectionString, string storeType, string storePath) { if (string.IsNullOrEmpty(connectionString)) { throw new ArgumentException("Token not found in X509Store and no new token provided!"); } SecureRandom random = new SecureRandom(); KeyGenerationParameters keyGenerationParameters = new KeyGenerationParameters(random, 2048); RsaKeyPairGenerator keyPairGenerator = new RsaKeyPairGenerator(); keyPairGenerator.Init(keyGenerationParameters); AsymmetricCipherKeyPair keys = keyPairGenerator.GenerateKeyPair(); ArrayList nameOids = new ArrayList(); nameOids.Add(X509Name.CN); ArrayList nameValues = new ArrayList(); nameValues.Add(name); X509Name subjectDN = new X509Name(nameOids, nameValues); X509Name issuerDN = subjectDN; X509V3CertificateGenerator cg = new X509V3CertificateGenerator(); cg.SetSerialNumber(BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random)); cg.SetIssuerDN(issuerDN); cg.SetSubjectDN(subjectDN); cg.SetNotBefore(DateTime.Now); cg.SetNotAfter(DateTime.Now.AddMonths(12)); cg.SetPublicKey(keys.Public); cg.AddExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.DataEncipherment)); // encrypt the token with the public key so only the owner of the assoc. private key can decrypt it and // "hide" it in the instruction code cert extension RSA rsa = RSA.Create(); RSAParameters rsaParams = new RSAParameters(); RsaKeyParameters keyParams = (RsaKeyParameters)keys.Public; rsaParams.Modulus = new byte[keyParams.Modulus.ToByteArrayUnsigned().Length]; keyParams.Modulus.ToByteArrayUnsigned().CopyTo(rsaParams.Modulus, 0); rsaParams.Exponent = new byte[keyParams.Exponent.ToByteArrayUnsigned().Length]; keyParams.Exponent.ToByteArrayUnsigned().CopyTo(rsaParams.Exponent, 0); rsa.ImportParameters(rsaParams); if (rsa != null) { byte[] bytes = rsa.Encrypt(Encoding.ASCII.GetBytes(connectionString), RSAEncryptionPadding.OaepSHA1); if (bytes != null) { cg.AddExtension(X509Extensions.InstructionCode, false, bytes); } else { RsaUtils.RSADispose(rsa); throw new CryptographicException("Can not encrypt IoTHub security token using generated public key!"); } } RsaUtils.RSADispose(rsa); // sign the cert with the private key ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA256WITHRSA", keys.Private, random); Org.BouncyCastle.X509.X509Certificate x509 = cg.Generate(signatureFactory); // create a PKCS12 store for the cert and its private key X509Certificate2 certificate = null; using (MemoryStream pfxData = new MemoryStream()) { Pkcs12StoreBuilder builder = new Pkcs12StoreBuilder(); builder.SetUseDerEncoding(true); Pkcs12Store pkcsStore = builder.Build(); X509CertificateEntry[] chain = new X509CertificateEntry[1]; string passcode = Guid.NewGuid().ToString(); chain[0] = new X509CertificateEntry(x509); pkcsStore.SetKeyEntry(name, new AsymmetricKeyEntry(keys.Private), chain); pkcsStore.Save(pfxData, passcode.ToCharArray(), random); // create X509Certificate2 object from PKCS12 file certificate = CertificateFactory.CreateCertificateFromPKCS12(pfxData.ToArray(), passcode); // handle each store type differently switch (storeType) { case CertificateStoreType.Directory: { // Add to DirectoryStore using (DirectoryCertificateStore store = new DirectoryCertificateStore()) { store.Open(storePath); X509CertificateCollection certificates = await store.Enumerate(); // remove any existing cert with our name from the store foreach (X509Certificate2 cert in certificates) { if (cert.SubjectName.Decode(X500DistinguishedNameFlags.None | X500DistinguishedNameFlags.DoNotUseQuotes).Equals("CN=" + name, StringComparison.OrdinalIgnoreCase)) { await store.Delete(cert.Thumbprint); } } // add new one await store.Add(certificate); } break; } case CertificateStoreType.X509Store: { // Add to X509Store using (X509Store store = new X509Store(storePath, StoreLocation.CurrentUser)) { store.Open(OpenFlags.ReadWrite); // remove any existing cert with our name from the store foreach (X509Certificate2 cert in store.Certificates) { if (cert.SubjectName.Decode(X500DistinguishedNameFlags.None | X500DistinguishedNameFlags.DoNotUseQuotes).Equals("CN=" + name, StringComparison.OrdinalIgnoreCase)) { store.Remove(cert); } } // add new cert to store try { store.Add(certificate); } catch (Exception e) { throw new Exception($"Not able to add cert to the requested store type '{storeType}' (exception message: '{e.Message}'."); } } break; } default: { throw new Exception($"The requested store type '{storeType}' is not supported. Please change."); } } return; } }
public static (CertPrivateKey, BcCertificate) GenerateRsaCACertificate(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"; #pragma warning disable CS0618 // Type or member is obsolete certificateGenerator.SetSignatureAlgorithm(signatureAlgorithm); #pragma warning restore CS0618 // Type or member is obsolete // 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 #pragma warning disable CS0618 // Type or member is obsolete var certificate = certificateGenerator.Generate(issuerKeyPair.Private, random); #pragma warning restore CS0618 // Type or member is obsolete // var x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate.GetEncoded()); // // Add CA certificate to Root store // addCertToStore(cert, StoreName.Root, StoreLocation.CurrentUser); var key = new CertPrivateKey { KeyPair = issuerKeyPair, }; return(key, certificate); }
public virtual X509CertificateBuilder SetNotBefore(DateTime notBefore) { X509V3CertificateGenerator.SetNotBefore(notBefore); return(this); }
public ICertificateBuilder SetNotBefore(DateTimeOffset notBefore) { certificateGenerator.SetNotBefore(notBefore.UtcDateTime); return(this); }
public void TestCreationECDSA() { IBigInteger ECParraGX = new BigInteger(Base64.Decode("D/qWPNyogWzMM7hkK+35BcPTWFc9Pyf7vTs8uaqv")); IBigInteger ECParraGY = new BigInteger(Base64.Decode("AhQXGxb1olGRv6s1LPRfuatMF+cx3ZTGgzSE/Q5R")); IBigInteger ECParraH = new BigInteger(Base64.Decode("AQ==")); IBigInteger ECParraN = new BigInteger(Base64.Decode("f///////////////f///nl6an12QcfvRUiaIkJ0L")); IBigInteger ECPubQX = new BigInteger(Base64.Decode("HWWi17Yb+Bm3PYr/DMjLOYNFhyOwX1QY7ZvqqM+l")); IBigInteger ECPubQY = new BigInteger(Base64.Decode("JrlJfxu3WGhqwtL/55BOs/wsUeiDFsvXcGhB8DGx")); IBigInteger ECPrivD = new BigInteger(Base64.Decode("GYQmd/NF1B+He1iMkWt3by2Az6Eu07t0ynJ4YCAo")); FPCurve curve = new FPCurve( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECDomainParameters ecDomain = new ECDomainParameters(curve, new FPPoint(curve, curve.FromBigInteger(ECParraGX), curve.FromBigInteger(ECParraGY)), ECParraN); ECPublicKeyParameters ecPub = new ECPublicKeyParameters( "ECDSA", new FPPoint(curve, curve.FromBigInteger(ECPubQX), curve.FromBigInteger(ECPubQY)), ecDomain); ECPrivateKeyParameters ecPriv = new ECPrivateKeyParameters("ECDSA", ECPrivD, ecDomain); IDictionary attrs = new Hashtable(); attrs[X509Name.C] = "AU"; attrs[X509Name.O] = "The Legion of the Bouncy Castle"; attrs[X509Name.L] = "Melbourne"; attrs[X509Name.ST] = "Victoria"; attrs[X509Name.E] = "*****@*****.**"; IList ord = new ArrayList(); ord.Add(X509Name.C); ord.Add(X509Name.O); ord.Add(X509Name.L); ord.Add(X509Name.ST); ord.Add(X509Name.E); IList values = new ArrayList(); values.Add("AU"); values.Add("The Legion of the Bouncy Castle"); values.Add("Melbourne"); values.Add("Victoria"); values.Add("*****@*****.**"); X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.SetSerialNumber(BigInteger.One); certGen.SetIssuerDN(new X509Name(ord, attrs)); certGen.SetNotBefore(DateTime.Today.Subtract(new TimeSpan(1, 0, 0, 0))); certGen.SetNotAfter(DateTime.Today.AddDays(1)); certGen.SetSubjectDN(new X509Name(ord, attrs)); certGen.SetPublicKey(ecPub); certGen.SetSignatureAlgorithm("SHA1WITHECDSA"); X509Certificate cert = certGen.Generate(ecPriv); // Assert.IsTrue((cert.IsValidNow && cert.Verify(ecPub)), "Certificate failed to be valid (ECDSA)"); cert.CheckValidity(); cert.Verify(ecPub); ISet dummySet = cert.GetNonCriticalExtensionOids(); if (dummySet != null) { foreach (string key in dummySet) { Console.WriteLine("\t{0}:\t{1}", key); } } Console.WriteLine(); dummySet = cert.GetNonCriticalExtensionOids(); if (dummySet != null) { foreach (string key in dummySet) { Console.WriteLine("\t{0}:\t{1}", key); } } Console.WriteLine(); }
public static void Main(string[] args) { var x509NameOids = CreateX509NameOidMapping(); var oids = new List <DerObjectIdentifier> (); var values = new List <string> (); var privateKey = new PrivateKeyOptions(); var options = new GeneratorOptions(); AsymmetricCipherKeyPair key; string section = null; string alias = null; options.Output = Path.ChangeExtension(args[0], ".pfx"); using (var reader = File.OpenText(args[0])) { string line; while ((line = reader.ReadLine()) != null) { if (line.Length == 0 || line[0] == '#') { continue; } if (line[0] == '[') { int endIndex = line.IndexOf(']'); if (endIndex == -1) { Console.Error.WriteLine("Incomplete section: ", line); return; } section = line.Substring(1, endIndex - 1); continue; } var kvp = line.Split(new char[] { '=' }, 2); var property = kvp[0].ToLowerInvariant().Trim(); var value = kvp[1].Trim(); switch (section.ToLowerInvariant()) { case "privatekey": switch (property) { case "algorithm": privateKey.Algorithm = value; break; case "bitlength": if (int.TryParse(value, out int bitLength)) { privateKey.BitLength = bitLength; } else { Console.Error.WriteLine("Invalid [PrivateKey] BitLength: {0}", value); return; } break; case "filename": privateKey.FileName = value; break; default: Console.Error.WriteLine("Unknown [PrivateKey] property: {0}", kvp[0]); return; } break; case "subject": if (x509NameOids.TryGetValue(property, out DerObjectIdentifier oid)) { if (oid == X509Name.CN) { alias = value; } else if (alias == null && oid == X509Name.E) { alias = value; } values.Add(value); oids.Add(oid); } else { Console.Error.WriteLine("Unknown [Subject] property: {0}", kvp[0]); return; } break; case "generator": switch (property) { case "basicconstraints": options.BasicConstraints = value; break; case "daysvalid": if (int.TryParse(value, out int days)) { options.DaysValid = days; } else { Console.Error.WriteLine("Invalid [Generator] DaysValid: {0}", value); return; } break; case "issuer": options.Issuer = value; break; case "issuerpassword": options.IssuerPassword = value; break; case "keyusage": options.KeyUsage = value; break; case "output": options.Output = value; break; case "password": options.Password = value; break; case "signaturealgorithm": options.SignatureAlgorithm = value; break; default: Console.Error.WriteLine("Unknown [Generator] property: {0}", kvp[0]); return; } break; default: Console.Error.WriteLine("Unknown section: {0}", section); break; } } } // Sanity Checks if (!string.IsNullOrEmpty(privateKey.FileName) && !File.Exists(privateKey.FileName)) { Console.Error.WriteLine("[PrivateKey] FileName `{0}' does not exist!", privateKey.FileName); return; } if (oids.Count == 0) { Console.Error.WriteLine("No [Subject] specified."); return; } if (string.IsNullOrEmpty(options.Issuer)) { Console.Error.WriteLine("[Generator] Issuer property cannot be empty!"); return; } else if (options.Issuer != "this" && !File.Exists(options.Issuer)) { Console.Error.WriteLine("[Generator] Issuer `{0}' does not exist!", options.Issuer); return; } if (string.IsNullOrEmpty(options.Output)) { Console.Error.WriteLine("[Generator] Output property cannot be empty!"); return; } var randomGenerator = new CryptoApiRandomGenerator(); var random = new SecureRandom(randomGenerator); var subject = new X509Name(oids, values); if (string.IsNullOrEmpty(privateKey.FileName)) { var keyGenerationParameters = new KeyGenerationParameters(random, privateKey.BitLength); IAsymmetricCipherKeyPairGenerator keyPairGenerator; switch (privateKey.Algorithm.ToLowerInvariant()) { case "rsa": keyPairGenerator = new RsaKeyPairGenerator(); break; case "ecdsa": keyPairGenerator = new ECKeyPairGenerator("ECDSA"); break; default: Console.Error.WriteLine("Unsupported PrivateKey algorithm: {0}", privateKey.Algorithm); return; } keyPairGenerator.Init(keyGenerationParameters); key = keyPairGenerator.GenerateKeyPair(); } else { try { key = LoadAsymmetricCipherKeyPair(privateKey.FileName); } catch (Exception ex) { Console.Error.WriteLine("[PrivateKey] Failed to load `{0}': {1}", privateKey.FileName, ex.Message); return; } } AsymmetricKeyParameter signingKey; X509Certificate issuerCertificate; X509Certificate[] chain; X509Name issuer; if (options.Issuer != "this") { try { chain = LoadPkcs12CertificateChain(options.Issuer, options.IssuerPassword, out signingKey); issuerCertificate = chain[0]; issuer = chain[0].SubjectDN; } catch (Exception ex) { Console.Error.WriteLine("[Generator] failed to load `{0}': {1}", options.Issuer, ex.Message); return; } } else { chain = new X509Certificate[0]; issuerCertificate = null; signingKey = key.Private; issuer = subject; } string signatureAlgorithm; if (string.IsNullOrEmpty(options.SignatureAlgorithm)) { if (signingKey is RsaPrivateCrtKeyParameters) { signatureAlgorithm = "SHA256WithRSA"; } else if (signingKey is ECPrivateKeyParameters ec) { if (ec.AlgorithmName == "ECGOST3410") { signatureAlgorithm = "GOST3411WithECGOST3410"; } else { signatureAlgorithm = "SHA256withECDSA"; } } else { signatureAlgorithm = "GOST3411WithGOST3410"; } } else { signatureAlgorithm = options.SignatureAlgorithm; } int serialNumberIndex = oids.IndexOf(X509Name.SerialNumber); BigInteger serialNumber; if (serialNumberIndex == -1) { serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(long.MaxValue), random); } else { try { serialNumber = new BigInteger(values[serialNumberIndex]); } catch { Console.Error.WriteLine("Invalid [Subject] SerialNumber: {0}", values[serialNumberIndex]); return; } } var notBefore = DateTime.UtcNow; var notAfter = notBefore.AddDays(options.DaysValid); var signatureFactory = new Asn1SignatureFactory(signatureAlgorithm, signingKey, random); var generator = new X509V3CertificateGenerator(); generator.SetSerialNumber(serialNumber); generator.SetPublicKey(key.Public); generator.SetNotBefore(notBefore); generator.SetNotAfter(notAfter); generator.SetSubjectDN(subject); generator.SetIssuerDN(issuer); generator.AddExtension(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifierStructure(key.Public)); if (issuerCertificate != null) { generator.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(issuerCertificate)); } if (!string.IsNullOrEmpty(options.BasicConstraints)) { var basicConstraints = options.BasicConstraints.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); bool critical = false; bool ca = false; foreach (var constraint in basicConstraints) { switch (constraint.Trim().ToLowerInvariant()) { case "critical": critical = true; break; case "ca:false": ca = false; break; case "ca:true": ca = true; break; } } generator.AddExtension(X509Extensions.BasicConstraints, critical, new BasicConstraints(ca)); } if (!string.IsNullOrEmpty(options.KeyUsage)) { var keyUsages = options.KeyUsage.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); bool critical = false; int keyUsage = 0; foreach (var usage in keyUsages) { switch (usage.Trim().ToLowerInvariant()) { case "critical": critical = true; break; case "digitalsignature": keyUsage |= X509KeyUsage.DigitalSignature; break; case "nonrepudiation": keyUsage |= X509KeyUsage.NonRepudiation; break; case "keyencipherment": keyUsage |= X509KeyUsage.KeyEncipherment; break; case "dataencipherment": keyUsage |= X509KeyUsage.DataEncipherment; break; case "keyagreement": keyUsage |= X509KeyUsage.KeyAgreement; break; case "keycertsign": keyUsage |= X509KeyUsage.KeyCertSign; break; case "crlsign": keyUsage |= X509KeyUsage.CrlSign; break; case "encipheronly": keyUsage |= X509KeyUsage.EncipherOnly; break; case "decipheronly": keyUsage |= X509KeyUsage.DecipherOnly; break; } } generator.AddExtension(X509Extensions.KeyUsage, critical, new KeyUsage(keyUsage)); } var certificate = generator.Generate(signatureFactory); var keyEntry = new AsymmetricKeyEntry(key.Private); var chainEntries = new X509CertificateEntry[chain.Length + 1]; chainEntries[0] = new X509CertificateEntry(certificate); for (int i = 0; i < chain.Length; i++) { chainEntries[i + 1] = new X509CertificateEntry(chain[i]); } var pkcs12 = new Pkcs12Store(); pkcs12.SetKeyEntry(alias ?? string.Empty, keyEntry, chainEntries); using (var stream = File.Create(options.Output)) pkcs12.Save(stream, options.Password.ToCharArray(), random); Console.WriteLine("{0} {1}", options.Output, GetFingerprint(certificate)); }
public Org.BouncyCastle.X509.X509Certificate GenerateCertificate(SecureRandom random, string subjectName, AsymmetricCipherKeyPair subjectKeyPair, BigInteger subjectSerialNumber, string[] subjectAlternativeNames, string issuerName, AsymmetricCipherKeyPair issuerKeyPair, BigInteger issuerSerialNumber, bool isCertificateAuthority, KeyPurposeID[] usages) { var certificateGenerator = new X509V3CertificateGenerator(); certificateGenerator.SetSerialNumber(subjectSerialNumber); // Set the signature algorithm. This is used to generate the thumbprint which is then signed // with the issuer's private key. We'll use SHA-256, which is (currently) considered fairly strong. const string signatureAlgorithm = "SHA256WithRSA"; certificateGenerator.SetSignatureAlgorithm(signatureAlgorithm); var issuerDN = new X509Name(issuerName); certificateGenerator.SetIssuerDN(issuerDN); // Note: The subject can be omitted if you specify a subject alternative name (SAN). var subjectDN = new X509Name(subjectName); certificateGenerator.SetSubjectDN(subjectDN); // Our certificate needs valid from/to values. var notBefore = DateTime.UtcNow.Date; var notAfter = notBefore.AddYears(20); certificateGenerator.SetNotBefore(notBefore); certificateGenerator.SetNotAfter(notAfter); // The subject's public key goes in the certificate. certificateGenerator.SetPublicKey(subjectKeyPair.Public); AddAuthorityKeyIdentifier(certificateGenerator, issuerDN, issuerKeyPair, issuerSerialNumber); AddSubjectKeyIdentifier(certificateGenerator, subjectKeyPair); AddBasicConstraints(certificateGenerator, isCertificateAuthority); if (usages != null && usages.Any()) { AddExtendedKeyUsage(certificateGenerator, usages); } if (subjectAlternativeNames != null && subjectAlternativeNames.Any()) { AddSubjectAlternativeNames(certificateGenerator, subjectAlternativeNames); } // The certificate is signed with the issuer's private key. var certificate = certificateGenerator.Generate(issuerKeyPair.Private, random); return(certificate); }
public string CreateAndStoreNewClientCertificate(string subjectName, string pvkPass, X509Certificate2 issuer) { X509V3CertificateGenerator generator = new X509V3CertificateGenerator(); // Generate pseudo random number var randomGen = new CryptoApiRandomGenerator(); var random = new SecureRandom(randomGen); // Set certificate serial number var serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random); generator.SetSerialNumber(serialNumber); // Set certificate subject name var subjectDN = new X509Name(subjectName); generator.SetSubjectDN(subjectDN); // Set issuer subject name var issuerDN = new X509Name(issuer.Subject); generator.SetIssuerDN(issuerDN); // Set certificate validity var notBefore = DateTime.UtcNow.Date; generator.SetNotBefore(notBefore); generator.SetNotAfter(notBefore.AddYears(2)); // Generate new RSA key pair for certificate var keyGeneratorParameters = new KeyGenerationParameters(random, RSAKeyStrength); var keyPairGenerator = new RsaKeyPairGenerator(); keyPairGenerator.Init(keyGeneratorParameters); var subjectKeyPair = keyPairGenerator.GenerateKeyPair(); // Import public key into generator generator.SetPublicKey(subjectKeyPair.Public); var issuerKeyPair = DotNetUtilities.GetKeyPair(issuer.PrivateKey); // Get key pair from .net issuer certificate //var issuerKeyPair = DotNetUtilities.GetKeyPair(issuer.PrivateKey); var issuerSerialNumber = new BigInteger(issuer.GetSerialNumber()); // Sign CA key with serial var caKeyIdentifier = new AuthorityKeyIdentifier( SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(issuerKeyPair.Public), new GeneralNames(new GeneralName(issuerDN)), issuerSerialNumber); generator.AddExtension( X509Extensions.AuthorityKeyIdentifier.Id, false, caKeyIdentifier); // Create signature factory to sign new cert ISignatureFactory signatureFactory = new Asn1SignatureFactory(SignatureAlgorithm, issuerKeyPair.Private); // Generate new bouncy castle certificate signed by issuer var newCertificate = generator.Generate(signatureFactory); var store = new Pkcs12Store(); string friendlyName = newCertificate.SubjectDN.ToString().Split('=')[1]; var certificateEntry = new X509CertificateEntry(newCertificate); // Set certificate store.SetCertificateEntry(friendlyName, certificateEntry); // Set private key store.SetKeyEntry( friendlyName, new AsymmetricKeyEntry(subjectKeyPair.Private), new X509CertificateEntry[] { certificateEntry }); var privatePath = @".\certs\" + $"{friendlyName}.pfx"; var publicPath = @".\certs\" + $"{friendlyName}.cer"; using (var stream = new MemoryStream()) { // Convert bouncy castle cert => .net cert store.Save(stream, pvkPass.ToCharArray(), random); var dotNetCertificate = new X509Certificate2( stream.ToArray(), pvkPass, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet); // Extract public part to store in server storage var publicCert = dotNetCertificate.Export(X509ContentType.Cert); // Extract private parameters to export into .pfx for distribution var privateCert = dotNetCertificate.Export(X509ContentType.Pfx, pvkPass); dotNetCertificate.Reset(); dotNetCertificate.Import(publicCert); // Store public cert info in storage using (var storage = new X509Store(StoreName.My, StoreLocation.LocalMachine)) { storage.Open(OpenFlags.ReadWrite); storage.Add(dotNetCertificate); storage.Close(); } dotNetCertificate.Dispose(); // Write private parameters to .pfx file to install at client File.WriteAllBytes(privatePath, privateCert); File.WriteAllBytes(publicPath, publicCert); } return(privatePath); }
public static X509Certificate2 CreateSelfSignedCertificateBasedOnPrivateKey(string commonNameValue, X509Name issuer, AsymmetricKeyParameter issuerPrivKey, bool isClientCertificate, bool isCaCertificate, int yearsUntilExpiration) { const int keyStrength = 2048; // Generating Random Numbers var random = GetSeededSecureRandom(); ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA512WITHRSA", issuerPrivKey, random); // The Certificate Generator X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator(); if (isClientCertificate) { certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage.Id, true, new ExtendedKeyUsage(KeyPurposeID.IdKPClientAuth)); } else { certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage.Id, true, new ExtendedKeyUsage(KeyPurposeID.IdKPServerAuth, KeyPurposeID.IdKPClientAuth)); } if (isCaCertificate) { certificateGenerator.AddExtension(X509Extensions.BasicConstraints.Id, true, new BasicConstraints(0)); certificateGenerator.AddExtension(X509Extensions.KeyUsage.Id, false, new X509KeyUsage(X509KeyUsage.KeyCertSign | X509KeyUsage.CrlSign)); } // Serial Number BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random); certificateGenerator.SetSerialNumber(serialNumber); // Issuer and Subject Name X509Name subjectDN = new X509Name("CN=" + commonNameValue); certificateGenerator.SetIssuerDN(issuer); certificateGenerator.SetSubjectDN(subjectDN); // Valid For DateTime notBefore = DateTime.UtcNow.Date.AddDays(-7); DateTime notAfter = notBefore.AddYears(yearsUntilExpiration); certificateGenerator.SetNotBefore(notBefore); certificateGenerator.SetNotAfter(notAfter); // Subject Public Key var keyGenerationParameters = new KeyGenerationParameters(random, keyStrength); var keyPairGenerator = new RsaKeyPairGenerator(); keyPairGenerator.Init(keyGenerationParameters); var subjectKeyPair = keyPairGenerator.GenerateKeyPair(); certificateGenerator.SetPublicKey(subjectKeyPair.Public); X509Certificate certificate = certificateGenerator.Generate(signatureFactory); var store = new Pkcs12Store(); string friendlyName = certificate.SubjectDN.ToString(); var certificateEntry = new X509CertificateEntry(certificate); store.SetCertificateEntry(friendlyName, certificateEntry); store.SetKeyEntry(friendlyName, new AsymmetricKeyEntry(subjectKeyPair.Private), new[] { certificateEntry }); var stream = new MemoryStream(); store.Save(stream, new char[0], random); var convertedCertificate = new X509Certificate2( stream.ToArray(), (string)null, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable); stream.Position = 0; return(convertedCertificate); }
internal PkiCertificate Create(X509Name issuerName, PkiKey issuerPrivateKey, X509Name subjectName, DateTimeOffset notBefore, DateTimeOffset notAfter, byte[] serialNumber, X509KeyUsage keyUsage = null, KeyPurposeID[] extKeyUsage = null) { // Based on: // https://stackoverflow.com/a/39456955/5428506 // https://github.com/bcgit/bc-csharp/blob/master/crypto/test/src/test/CertTest.cs var pubKey = _keyPair?.PublicKey.NativeKey ?? PublicKey.NativeKey; var sigFactory = ComputeSignatureAlgorithm(issuerPrivateKey.NativeKey); var certGen = new X509V3CertificateGenerator(); certGen.SetSerialNumber(new BigInteger(serialNumber)); certGen.SetIssuerDN(issuerName); certGen.SetSubjectDN(subjectName); certGen.SetNotBefore(notBefore.UtcDateTime); certGen.SetNotAfter(notAfter.UtcDateTime); certGen.SetPublicKey(pubKey); if (keyUsage == null) { keyUsage = new X509KeyUsage(X509KeyUsage.KeyEncipherment | X509KeyUsage.DigitalSignature); } if (extKeyUsage == null) { extKeyUsage = new[] { KeyPurposeID.IdKPClientAuth, KeyPurposeID.IdKPServerAuth } } ; certGen.AddExtension("2.5.29.15", true, keyUsage); certGen.AddExtension("2.5.29.37", true, new DerSequence(extKeyUsage)); // Based on: // https://boredwookie.net/blog/bouncy-castle-add-a-subject-alternative-name-when-creating-a-cer foreach (var ext in CertificateExtensions) { // certGen.AddExtension(ext.Identifier, ext.Value.IsCritical, ext.Value.Value); certGen.AddExtension(ext.Identifier, ext.IsCritical, ext.Value); } var bcCert = certGen.Generate(sigFactory); return(new PkiCertificate { NativeCertificate = bcCert, }); // Compare to LE-issued Certs: // Enhanced Key Usage: // Server Authentication (1.3.6.1.5.5.7.3.1) // Client Authentication (1.3.6.1.5.5.7.3.2) // Subject Key Identifier: // e05bf2ba81d8d3845ff45b5638551e64ca19133d // Authority Key Identifier: // KeyID=a84a6a63047dddbae6d139b7a64565eff3a8eca1 // Authority Information Access: // [1]Authority Info Access // Access Method=On-line Certificate Status Protocol (1.3.6.1.5.5.7.48.1) // Alternative Name: // URL=http://ocsp.int-x3.letsencrypt.org // [2]Authority Info Access // Access Method=Certification Authority Issuer (1.3.6.1.5.5.7.48.2) // Alternative Name: // URL=http://cert.int-x3.letsencrypt.org/ // Certificate Policies: // ... // SCT List: // ... // Key Usage: // Digital Signature, Key Encipherment (a0) // Basic Constraints: // Subject Type=End Entity // Path Length Constraint=None // CA: // Key Usage: // Digital Signature, Certificate Signing, Off-line CRL Signing, CRL Signing (86) }
/// <summary> /// Create a self signed certificate with bouncy castle. /// </summary> public static X509Certificate2 GenerateCertificate( string subjectName, Action <X509V3CertificateGenerator> modifyGenerator, string signatureAlgorithm = "SHA256WITHRSA", int publicKeyLength = 2048, ChainCertificateRequest chainCertificateRequest = null) { if (string.IsNullOrEmpty(subjectName)) { subjectName = "NuGetTest"; } var random = new SecureRandom(); var keyPair = GenerateKeyPair(publicKeyLength); // Create cert var subjectDN = $"CN={subjectName}"; var certGen = new X509V3CertificateGenerator(); certGen.SetSubjectDN(new X509Name(subjectDN)); // default to new key pair var issuerPrivateKey = keyPair.Private; var keyUsage = KeyUsage.DigitalSignature; var issuerDN = chainCertificateRequest?.IssuerDN ?? subjectDN; certGen.SetIssuerDN(new X509Name(issuerDN)); #if IS_DESKTOP if (chainCertificateRequest != null) { if (chainCertificateRequest.Issuer != null) { // for a certificate with an issuer assign Authority Key Identifier var issuer = chainCertificateRequest?.Issuer; var bcIssuer = DotNetUtilities.FromX509Certificate(issuer); var authorityKeyIdentifier = new AuthorityKeyIdentifierStructure(bcIssuer); issuerPrivateKey = DotNetUtilities.GetKeyPair(issuer.PrivateKey).Private; certGen.AddExtension(X509Extensions.AuthorityKeyIdentifier.Id, false, authorityKeyIdentifier); } if (chainCertificateRequest.ConfigureCrl) { // for a certificate in a chain create CRL distribution point extension var crlServerUri = $"{chainCertificateRequest.CrlServerBaseUri}{issuerDN}.crl"; var generalName = new Org.BouncyCastle.Asn1.X509.GeneralName(Org.BouncyCastle.Asn1.X509.GeneralName.UniformResourceIdentifier, new DerIA5String(crlServerUri)); var distPointName = new DistributionPointName(new GeneralNames(generalName)); var distPoint = new DistributionPoint(distPointName, null, null); certGen.AddExtension(X509Extensions.CrlDistributionPoints, critical: false, extensionValue: new DerSequence(distPoint)); } if (chainCertificateRequest.IsCA) { // update key usage with CA cert sign and crl sign attributes keyUsage |= KeyUsage.CrlSign | KeyUsage.KeyCertSign; } } #endif certGen.SetNotAfter(DateTime.UtcNow.Add(TimeSpan.FromHours(1))); certGen.SetNotBefore(DateTime.UtcNow.Subtract(TimeSpan.FromHours(1))); certGen.SetPublicKey(keyPair.Public); var serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(long.MaxValue), random); certGen.SetSerialNumber(serialNumber); var subjectKeyIdentifier = new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keyPair.Public)); certGen.AddExtension(X509Extensions.SubjectKeyIdentifier.Id, false, subjectKeyIdentifier); certGen.AddExtension(X509Extensions.KeyUsage.Id, false, new KeyUsage(keyUsage)); certGen.AddExtension(X509Extensions.BasicConstraints.Id, true, new BasicConstraints(chainCertificateRequest?.IsCA ?? false)); // Allow changes modifyGenerator?.Invoke(certGen); var signatureFactory = new Asn1SignatureFactory(signatureAlgorithm, issuerPrivateKey, random); var certificate = certGen.Generate(signatureFactory); var certResult = new X509Certificate2(certificate.GetEncoded()); #if IS_DESKTOP certResult.PrivateKey = DotNetUtilities.ToRSA(keyPair.Private as RsaPrivateCrtKeyParameters); #endif return(certResult); }
private static X509Certificate2 CreateSelfSignedCertificate(string agentGuid, string logAnalyticsWorkspaceId) { var random = new SecureRandom(); var certificateGenerator = new X509V3CertificateGenerator(); var serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random); certificateGenerator.SetSerialNumber(serialNumber); var dirName = string.Format("CN={0}, CN={1}, OU=Linux Monitoring Agent, O=Microsoft", logAnalyticsWorkspaceId, agentGuid); X509Name certName = new X509Name(dirName); certificateGenerator.SetIssuerDN(certName); certificateGenerator.SetSubjectDN(certName); certificateGenerator.SetNotBefore(DateTime.UtcNow.Date); certificateGenerator.SetNotAfter(DateTime.UtcNow.Date.AddYears(1)); const int strength = 2048; var keyGenerationParameters = new KeyGenerationParameters(random, strength); var keyPairGenerator = new RsaKeyPairGenerator(); keyPairGenerator.Init(keyGenerationParameters); var subjectKeyPair = keyPairGenerator.GenerateKeyPair(); certificateGenerator.SetPublicKey(subjectKeyPair.Public); // Get Private key for the Certificate TextWriter textWriter = new StringWriter(); PemWriter pemWriter = new PemWriter(textWriter); pemWriter.WriteObject(subjectKeyPair.Private); pemWriter.Writer.Flush(); string privateKeyString = textWriter.ToString(); // The magic extension that on commenting made the certificate work with ODS!!!!! //certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage.Id, false, // new ExtendedKeyUsage(new[] { KeyPurposeID.IdKPServerAuth, KeyPurposeID.IdKPClientAuth })); //certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage.Id, false, // new AuthorityKeyIdentifier( // new GeneralNames(new GeneralName(certName)), serialNumber)); //certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage.Id, false, // new AuthorityKeyIdentifier( // SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(subjectKeyPair.Public), // new GeneralNames(new GeneralName(certName)), serialNumber)); var issuerKeyPair = subjectKeyPair; var signatureFactory = new Asn1SignatureFactory(Constants.DEFAULT_SIGNATURE_ALOGIRTHM, issuerKeyPair.Private); var bouncyCert = certificateGenerator.Generate(signatureFactory); // Lets convert it to X509Certificate2 X509Certificate2 certificate; Pkcs12Store store = new Pkcs12StoreBuilder().Build(); store.SetKeyEntry($"{agentGuid}_key", new AsymmetricKeyEntry(subjectKeyPair.Private), new[] { new X509CertificateEntry(bouncyCert) }); string exportpw = Guid.NewGuid().ToString("x"); using (var ms = new MemoryStream()) { store.Save(ms, exportpw.ToCharArray(), random); certificate = new X509Certificate2(ms.ToArray(), exportpw, X509KeyStorageFlags.Exportable); } // Get the value. string resultsTrue = certificate.ToString(true); // Display the value to the console. Console.WriteLine(resultsTrue); //Get Certificate in PEM format StringBuilder builder = new StringBuilder(); builder.AppendLine("-----BEGIN CERTIFICATE-----"); builder.AppendLine( Convert.ToBase64String(certificate.RawData, Base64FormattingOptions.InsertLineBreaks)); builder.AppendLine("-----END CERTIFICATE-----"); Console.WriteLine("Writing certificate and key to two files"); string crt_location = "C://oms.crt"; string key_location = "C://oms.key"; try { if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("CI_CRT_LOCATION"))) { crt_location = Environment.GetEnvironmentVariable("CI_CRT_LOCATION"); } } catch (Exception ex) { Console.WriteLine("Reading env variables (CI_CRT_LOCATION) is too much to ask for " + ex.Message); } try { if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("CI_KEY_LOCATION"))) { key_location = Environment.GetEnvironmentVariable("CI_KEY_LOCATION"); } } catch (Exception ex) { Console.WriteLine("Reading env variables (CI_KEY_LOCATION) is too much to ask for " + ex.Message); } File.WriteAllText(crt_location, builder.ToString()); File.WriteAllText(key_location, privateKeyString); // Saving certificate in the store // SaveCertificate(certificate); // For local testing : reading a random cert //string newcer = "E://oms.crt"; //X509Certificate2 cert1 = new X509Certificate2(newcer); return(certificate); }
public X509Certificate2 GenerateSelfSignedCertificate(string name) { var randomGenerator = new CryptoApiRandomGenerator(); var random = new SecureRandom(randomGenerator); var certificateGenerator = new X509V3CertificateGenerator(); var serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(long.MaxValue), random); certificateGenerator.SetSerialNumber(serialNumber); var subjectDN = new X509Name(name); var issuerDN = subjectDN; certificateGenerator.SetIssuerDN(issuerDN); certificateGenerator.SetSubjectDN(subjectDN); var notBefore = DateTime.UtcNow.Date; var notAfter = notBefore.AddYears(ExpireTimeInYears); certificateGenerator.SetNotBefore(notBefore); certificateGenerator.SetNotAfter(notAfter); var keyGenerationParameters = new KeyGenerationParameters(random, KeyStrength); var keyPairGenerator = new RsaKeyPairGenerator(); keyPairGenerator.Init(keyGenerationParameters); var subjectKeyPair = keyPairGenerator.GenerateKeyPair(); certificateGenerator.SetPublicKey(subjectKeyPair.Public); var issuerKeyPair = subjectKeyPair; var signatureFactory = new Asn1SignatureFactory("SHA512WITHRSA", issuerKeyPair.Private, random); var certificate = certificateGenerator.Generate(signatureFactory); var info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private); var x509 = new X509Certificate2(certificate.GetEncoded()); var privateKey = info.ParsePrivateKey(); var sequence = (Asn1Sequence)Asn1Object.FromByteArray(privateKey.GetDerEncoded()); if (sequence.Count != 9) { throw new PemException("Malformed sequence in RSA private key."); } var rsa = RsaPrivateKeyStructure.GetInstance(sequence); var rsaParameters = new RsaPrivateCrtKeyParameters( rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, rsa.Coefficient); var privateKeyRSA = DotNetUtilities.ToRSA(rsaParameters); var csp = new CspParameters { KeyContainerName = "Shapeshifter" }; var rsaPrivate = new RSACryptoServiceProvider(csp); rsaPrivate.ImportParameters(privateKeyRSA.ExportParameters(true)); x509.PrivateKey = rsaPrivate; return(x509); }
static void Main(string[] args) { string subjectName = "testsubject"; var randomGenerator = new CryptoApiRandomGenerator(); var random = new SecureRandom(randomGenerator); var certificateGenerator = new X509V3CertificateGenerator(); var serialNumber = BigIntegers.CreateRandomInRange( BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random); certificateGenerator.SetSerialNumber(serialNumber); const string signatureAlgorithm = "SHA256WithRSA"; certificateGenerator.SetSignatureAlgorithm(signatureAlgorithm); var subjectDN = new Org.BouncyCastle.Asn1.X509.X509Name(subjectName); var issuerDN = subjectDN; certificateGenerator.SetIssuerDN(issuerDN); certificateGenerator.SetSubjectDN(subjectDN); var notBefore = DateTime.UtcNow.Date; var notAfter = notBefore.AddYears(2); certificateGenerator.SetNotBefore(notBefore); certificateGenerator.SetNotAfter(notAfter); const int strength = 2048; var keyGenerationParameters = new KeyGenerationParameters(random, strength); var keyPairGenerator = new RsaKeyPairGenerator(); keyPairGenerator.Init(keyGenerationParameters); var subjectKeyPair = keyPairGenerator.GenerateKeyPair(); certificateGenerator.SetPublicKey(subjectKeyPair.Public); var issuerKeyPair = subjectKeyPair; var certificate = certificateGenerator.Generate(issuerKeyPair.Private, random); PdfReader reader = new PdfReader(this.inputPDF); ////var kpgen = new RsaKeyPairGenerator(); ////kpgen.Init(new KeyGenerationParameters(new SecureRandom(new CryptoApiRandomGenerator()), 1024)); ////var kp = kpgen.GenerateKeyPair(); ////var gen = new X509V3CertificateGenerator(); ////var certName = new Org.BouncyCastle.Asn1.X509.X509Name("CN=" + subjectName); ////var serialNo = BigInteger.ProbablePrime(120, new Random()); ////gen.SetSerialNumber(serialNo); ////gen.SetSubjectDN(certName); ////gen.SetIssuerDN(certName); ////gen.SetNotAfter(DateTime.Now.AddYears(100)); ////gen.SetNotBefore(DateTime.Now.Subtract(new TimeSpan(7, 0, 0, 0))); ////gen.SetSignatureAlgorithm("MD5WithRSA"); ////gen.SetPublicKey(kp.Public); ////gen.AddExtension( //// X509Extensions.AuthorityKeyIdentifier.Id, //// false, //// new AuthorityKeyIdentifier( //// SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(kp.Public), //// new GeneralNames(new GeneralName(certName)), //// serialNo)); ////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(kp.Private); ////DotNetUtilities.ToX509Certificate(newCert).Export(System.Security.Cryptography.X509Certificates.X509ContentType.Pkcs12, "password"); }
public void TestCreationDSA() { BigInteger DSAParaG = new BigInteger(Base64.Decode("AL0fxOTq10OHFbCf8YldyGembqEu08EDVzxyLL29Zn/t4It661YNol1rnhPIs+cirw+yf9zeCe+KL1IbZ/qIMZM=")); BigInteger DSAParaP = new BigInteger(Base64.Decode("AM2b/UeQA+ovv3dL05wlDHEKJ+qhnJBsRT5OB9WuyRC830G79y0R8wuq8jyIYWCYcTn1TeqVPWqiTv6oAoiEeOs=")); BigInteger DSAParaQ = new BigInteger(Base64.Decode("AIlJT7mcKL6SUBMmvm24zX1EvjNx")); BigInteger DSAPublicY = new BigInteger(Base64.Decode("TtWy2GuT9yGBWOHi1/EpCDa/bWJCk2+yAdr56rAcqP0eHGkMnA9s9GJD2nGU8sFjNHm55swpn6JQb8q0agrCfw==")); BigInteger DsaPrivateX = new BigInteger(Base64.Decode("MMpBAxNlv7eYfxLTZ2BItJeD31A=")); DsaParameters para = new DsaParameters(DSAParaP, DSAParaQ, DSAParaG); DsaPrivateKeyParameters dsaPriv = new DsaPrivateKeyParameters(DsaPrivateX, para); DsaPublicKeyParameters dsaPub = new DsaPublicKeyParameters(DSAPublicY, para); IDictionary attrs = new Hashtable(); attrs[X509Name.C] = "AU"; attrs[X509Name.O] = "The Legion of the Bouncy Castle"; attrs[X509Name.L] = "Melbourne"; attrs[X509Name.ST] = "Victoria"; attrs[X509Name.E] = "*****@*****.**"; IList ord = new ArrayList(); ord.Add(X509Name.C); ord.Add(X509Name.O); ord.Add(X509Name.L); ord.Add(X509Name.ST); ord.Add(X509Name.E); IList values = new ArrayList(); values.Add("AU"); values.Add("The Legion of the Bouncy Castle"); values.Add("Melbourne"); values.Add("Victoria"); values.Add("*****@*****.**"); X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.SetSerialNumber(BigInteger.One); certGen.SetIssuerDN(new X509Name(ord, attrs)); certGen.SetNotBefore(DateTime.UtcNow.AddDays(-1)); certGen.SetNotAfter(DateTime.UtcNow.AddDays(1)); certGen.SetSubjectDN(new X509Name(ord, attrs)); certGen.SetPublicKey(dsaPub); certGen.SetSignatureAlgorithm("SHA1WITHDSA"); X509Certificate cert = certGen.Generate(dsaPriv); // Assert.IsTrue((cert.IsValidNow && cert.Verify(dsaPub)), "Certificate failed to be valid (DSA Test)"); cert.CheckValidity(); cert.Verify(dsaPub); //ISet dummySet = cert.GetNonCriticalExtensionOids(); //if (dummySet != null) //{ // foreach (string key in dummySet) // { // Console.WriteLine("\t{0}:\t{1}", key); // } //} //Console.WriteLine(); //dummySet = cert.GetNonCriticalExtensionOids(); //if (dummySet != null) //{ // foreach (string key in dummySet) // { // Console.WriteLine("\t{0}:\t{1}", key); // } //} //Console.WriteLine(); }
public void TestCreationRSA() { BigInteger rsaPubMod = new BigInteger(Base64.Decode("AIASoe2PQb1IP7bTyC9usjHP7FvnUMVpKW49iuFtrw/dMpYlsMMoIU2jupfifDpdFxIktSB4P+6Ymg5WjvHKTIrvQ7SR4zV4jaPTu56Ys0pZ9EDA6gb3HLjtU+8Bb1mfWM+yjKxcPDuFjwEtjGlPHg1Vq+CA9HNcMSKNn2+tW6qt")); BigInteger rsaPubExp = new BigInteger(Base64.Decode("EQ==")); BigInteger rsaPrivMod = new BigInteger(Base64.Decode("AIASoe2PQb1IP7bTyC9usjHP7FvnUMVpKW49iuFtrw/dMpYlsMMoIU2jupfifDpdFxIktSB4P+6Ymg5WjvHKTIrvQ7SR4zV4jaPTu56Ys0pZ9EDA6gb3HLjtU+8Bb1mfWM+yjKxcPDuFjwEtjGlPHg1Vq+CA9HNcMSKNn2+tW6qt")); BigInteger rsaPrivDP = new BigInteger(Base64.Decode("JXzfzG5v+HtLJIZqYMUefJfFLu8DPuJGaLD6lI3cZ0babWZ/oPGoJa5iHpX4Ul/7l3s1PFsuy1GhzCdOdlfRcQ==")); BigInteger rsaPrivDQ = new BigInteger(Base64.Decode("YNdJhw3cn0gBoVmMIFRZzflPDNthBiWy/dUMSRfJCxoZjSnr1gysZHK01HteV1YYNGcwPdr3j4FbOfri5c6DUQ==")); BigInteger rsaPrivExp = new BigInteger(Base64.Decode("DxFAOhDajr00rBjqX+7nyZ/9sHWRCCp9WEN5wCsFiWVRPtdB+NeLcou7mWXwf1Y+8xNgmmh//fPV45G2dsyBeZbXeJwB7bzx9NMEAfedchyOwjR8PYdjK3NpTLKtZlEJ6Jkh4QihrXpZMO4fKZWUm9bid3+lmiq43FwW+Hof8/E=")); BigInteger rsaPrivP = new BigInteger(Base64.Decode("AJ9StyTVW+AL/1s7RBtFwZGFBgd3zctBqzzwKPda6LbtIFDznmwDCqAlIQH9X14X7UPLokCDhuAa76OnDXb1OiE=")); BigInteger rsaPrivQ = new BigInteger(Base64.Decode("AM3JfD79dNJ5A3beScSzPtWxx/tSLi0QHFtkuhtSizeXdkv5FSba7lVzwEOGKHmW829bRoNxThDy4ds1IihW1w0=")); BigInteger rsaPrivQinv = new BigInteger(Base64.Decode("Lt0g7wrsNsQxuDdB8q/rH8fSFeBXMGLtCIqfOec1j7FEIuYA/ACiRDgXkHa0WgN7nLXSjHoy630wC5Toq8vvUg==")); RsaKeyParameters rsaPublic = new RsaKeyParameters(false, rsaPubMod, rsaPubExp); RsaPrivateCrtKeyParameters rsaPrivate = new RsaPrivateCrtKeyParameters(rsaPrivMod, rsaPubExp, rsaPrivExp, rsaPrivP, rsaPrivQ, rsaPrivDP, rsaPrivDQ, rsaPrivQinv); IDictionary attrs = new Hashtable(); attrs[X509Name.C] = "AU"; attrs[X509Name.O] = "The Legion of the Bouncy Castle"; attrs[X509Name.L] = "Melbourne"; attrs[X509Name.ST] = "Victoria"; attrs[X509Name.E] = "*****@*****.**"; IList ord = new ArrayList(); ord.Add(X509Name.C); ord.Add(X509Name.O); ord.Add(X509Name.L); ord.Add(X509Name.ST); ord.Add(X509Name.E); IList values = new ArrayList(); values.Add("AU"); values.Add("The Legion of the Bouncy Castle"); values.Add("Melbourne"); values.Add("Victoria"); values.Add("*****@*****.**"); X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.SetSerialNumber(BigInteger.One); certGen.SetIssuerDN(new X509Name(ord, attrs)); certGen.SetNotBefore(DateTime.UtcNow.AddDays(-1)); certGen.SetNotAfter(DateTime.UtcNow.AddDays(1)); certGen.SetSubjectDN(new X509Name(ord, attrs)); certGen.SetPublicKey(rsaPublic); certGen.SetSignatureAlgorithm("MD5WithRSAEncryption"); X509Certificate cert = certGen.Generate(rsaPrivate); // Assert.IsTrue((cert.IsValidNow && cert.Verify(rsaPublic)),"Certificate failed to be valid (RSA)"); cert.CheckValidity(); cert.Verify(rsaPublic); //Console.WriteLine(ASN1Dump.DumpAsString(cert.ToAsn1Object())); //ISet dummySet = cert.GetNonCriticalExtensionOids(); //if (dummySet != null) //{ // foreach (string key in dummySet) // { // Console.WriteLine("\t{0}:\t{1}", key); // } //} //Console.WriteLine(); //dummySet = cert.GetNonCriticalExtensionOids(); //if (dummySet != null) //{ // foreach (string key in dummySet) // { // Console.WriteLine("\t{0}:\t{1}", key); // } //} //Console.WriteLine(); }
// Only the ctor should be calling with isAuthority = true // if isAuthority, value for isMachineCert doesn't matter private X509CertificateContainer CreateCertificate(bool isAuthority, bool isMachineCert, X509Certificate signingCertificate, CertificateCreationSettings certificateCreationSettings) { if (certificateCreationSettings == null) { if (isAuthority) { certificateCreationSettings = new CertificateCreationSettings(); } else { throw new Exception("Parameter certificateCreationSettings cannot be null when isAuthority is false"); } } // Set to default cert creation settings if not set if (certificateCreationSettings.ValidityNotBefore == default(DateTime)) { certificateCreationSettings.ValidityNotBefore = _defaultValidityNotBefore; } if (certificateCreationSettings.ValidityNotAfter == default(DateTime)) { certificateCreationSettings.ValidityNotAfter = _defaultValidityNotAfter; } if (!isAuthority ^ (signingCertificate != null)) { throw new ArgumentException("Either isAuthority == true or signingCertificate is not null"); } string subject = certificateCreationSettings.Subject; // If certificateCreationSettings.SubjectAlternativeNames == null, then we should add exactly one SubjectAlternativeName == Subject // so that the default certificate generated is compatible with mainline scenarios // However, if certificateCreationSettings.SubjectAlternativeNames == string[0], then allow this as this is a legit scenario we want to test out if (certificateCreationSettings.SubjectAlternativeNames == null) { certificateCreationSettings.SubjectAlternativeNames = new string[1] { subject }; } string[] subjectAlternativeNames = certificateCreationSettings.SubjectAlternativeNames; if (!isAuthority && string.IsNullOrWhiteSpace(subject)) { throw new ArgumentException("Certificate Subject must not be an empty string or only whitespace", "creationSettings.Subject"); } EnsureInitialized(); s_certGenerator.Reset(); s_certGenerator.SetSignatureAlgorithm(_signatureAlthorithm); X509Name authorityX509Name = CreateX509Name(_authorityCanonicalName); var serialNum = new BigInteger(64 /*sizeInBits*/, _random).Abs(); var keyPair = isAuthority ? _authorityKeyPair : _keyPairGenerator.GenerateKeyPair(); if (isAuthority) { s_certGenerator.SetIssuerDN(authorityX509Name); s_certGenerator.SetSubjectDN(authorityX509Name); var authorityKeyIdentifier = new AuthorityKeyIdentifier( SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(_authorityKeyPair.Public), new GeneralNames(new GeneralName(authorityX509Name)), serialNum); s_certGenerator.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, authorityKeyIdentifier); s_certGenerator.AddExtension(X509Extensions.KeyUsage, false, new KeyUsage(X509KeyUsage.DigitalSignature | X509KeyUsage.KeyAgreement | X509KeyUsage.KeyCertSign | X509KeyUsage.KeyEncipherment | X509KeyUsage.CrlSign)); } else { X509Name subjectName = CreateX509Name(subject); s_certGenerator.SetIssuerDN(PrincipalUtilities.GetSubjectX509Principal(signingCertificate)); s_certGenerator.SetSubjectDN(subjectName); s_certGenerator.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(_authorityKeyPair.Public)); s_certGenerator.AddExtension(X509Extensions.KeyUsage, false, new KeyUsage(X509KeyUsage.DigitalSignature | X509KeyUsage.KeyAgreement | X509KeyUsage.KeyEncipherment)); } s_certGenerator.AddExtension(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifierStructure(keyPair.Public)); s_certGenerator.SetSerialNumber(serialNum); s_certGenerator.SetNotBefore(certificateCreationSettings.ValidityNotBefore); s_certGenerator.SetNotAfter(certificateCreationSettings.ValidityNotAfter); s_certGenerator.SetPublicKey(keyPair.Public); s_certGenerator.AddExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(isAuthority)); s_certGenerator.AddExtension(X509Extensions.ExtendedKeyUsage, false, new ExtendedKeyUsage(KeyPurposeID.IdKPServerAuth, KeyPurposeID.IdKPClientAuth)); if (!isAuthority) { if (isMachineCert) { List <Asn1Encodable> subjectAlternativeNamesAsAsn1EncodableList = new List <Asn1Encodable>(); // All endpoints should also be in the Subject Alt Names for (int i = 0; i < subjectAlternativeNames.Length; i++) { if (!string.IsNullOrWhiteSpace(subjectAlternativeNames[i])) { // Machine certs can have additional DNS names subjectAlternativeNamesAsAsn1EncodableList.Add(new GeneralName(GeneralName.DnsName, subjectAlternativeNames[i])); } } s_certGenerator.AddExtension(X509Extensions.SubjectAlternativeName, true, new DerSequence(subjectAlternativeNamesAsAsn1EncodableList.ToArray())); } else { if (subjectAlternativeNames.Length > 1) { var subjectAlternativeNamesAsAsn1EncodableList = new Asn1EncodableVector(); // Only add a SAN for the user if there are any for (int i = 1; i < subjectAlternativeNames.Length; i++) { if (!string.IsNullOrWhiteSpace(subjectAlternativeNames[i])) { Asn1EncodableVector otherNames = new Asn1EncodableVector(); otherNames.Add(new DerObjectIdentifier(_upnObjectId)); otherNames.Add(new DerTaggedObject(true, 0, new DerUtf8String(subjectAlternativeNames[i]))); Asn1Object genName = new DerTaggedObject(false, 0, new DerSequence(otherNames)); subjectAlternativeNamesAsAsn1EncodableList.Add(genName); } } s_certGenerator.AddExtension(X509Extensions.SubjectAlternativeName, true, new DerSequence(subjectAlternativeNamesAsAsn1EncodableList)); } } } // Our CRL Distribution Point has the serial number in the query string to fool Windows into doing a fresh query // rather than using a cached copy of the CRL in the case where the CRL has been previously accessed before var crlDistributionPoints = new DistributionPoint[2] { new DistributionPoint(new DistributionPointName( new GeneralNames(new GeneralName( GeneralName.UniformResourceIdentifier, string.Format("{0}?serialNum={1}", _crlUri, serialNum.ToString(radix: 16))))), null, null), new DistributionPoint(new DistributionPointName( new GeneralNames(new GeneralName( GeneralName.UniformResourceIdentifier, string.Format("{0}?serialNum={1}", _crlUri, serialNum.ToString(radix: 16))))), null, new GeneralNames(new GeneralName(authorityX509Name))) }; var revocationListExtension = new CrlDistPoint(crlDistributionPoints); s_certGenerator.AddExtension(X509Extensions.CrlDistributionPoints, false, revocationListExtension); X509Certificate cert = s_certGenerator.Generate(_authorityKeyPair.Private, _random); switch (certificateCreationSettings.ValidityType) { case CertificateValidityType.Revoked: RevokeCertificateBySerialNumber(serialNum.ToString(radix: 16)); break; case CertificateValidityType.Expired: break; default: EnsureCertificateIsValid(cert); break; } // For now, given that we don't know what format to return it in, preserve the formats so we have // the flexibility to do what we need to X509CertificateContainer container = new X509CertificateContainer(); X509CertificateEntry[] chain = new X509CertificateEntry[1]; chain[0] = new X509CertificateEntry(cert); Pkcs12Store store = new Pkcs12StoreBuilder().Build(); store.SetKeyEntry( certificateCreationSettings.FriendlyName != null ? certificateCreationSettings.FriendlyName : string.Empty, new AsymmetricKeyEntry(keyPair.Private), chain); using (MemoryStream stream = new MemoryStream()) { store.Save(stream, _password.ToCharArray(), _random); container.Pfx = stream.ToArray(); } X509Certificate2 outputCert; if (isAuthority) { // don't hand out the private key for the cert when it's the authority outputCert = new X509Certificate2(cert.GetEncoded()); } else { // Otherwise, allow encode with the private key. note that X509Certificate2.RawData will not provide the private key // you will have to re-export this cert if needed outputCert = new X509Certificate2(container.Pfx, _password, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet); } container.Subject = subject; container.InternalCertificate = cert; container.Certificate = outputCert; container.Thumbprint = outputCert.Thumbprint; Trace.WriteLine("[CertificateGenerator] generated a certificate:"); Trace.WriteLine(string.Format(" {0} = {1}", "isAuthority", isAuthority)); if (!isAuthority) { Trace.WriteLine(string.Format(" {0} = {1}", "Signed by", signingCertificate.SubjectDN)); Trace.WriteLine(string.Format(" {0} = {1}", "Subject (CN) ", subject)); Trace.WriteLine(string.Format(" {0} = {1}", "Subject Alt names ", string.Join(", ", subjectAlternativeNames))); Trace.WriteLine(string.Format(" {0} = {1}", "Friendly Name ", certificateCreationSettings.FriendlyName)); } Trace.WriteLine(string.Format(" {0} = {1}", "HasPrivateKey:", outputCert.HasPrivateKey)); Trace.WriteLine(string.Format(" {0} = {1}", "Thumbprint", outputCert.Thumbprint)); Trace.WriteLine(string.Format(" {0} = {1}", "CertificateValidityType", certificateCreationSettings.ValidityType)); return(container); }
public async Task ValidateMergeCertificate() { string serverCertificateName = Recording.GenerateId(); // Generate the request. CertificatePolicy policy = new CertificatePolicy(WellKnownIssuerNames.Unknown, "CN=Azure SDK") { CertificateTransparency = false, ContentType = CertificateContentType.Pkcs12, }; CertificateOperation operation = await Client.StartCreateCertificateAsync(serverCertificateName, policy); RegisterForCleanup(serverCertificateName); await using IAsyncDisposable disposableOperation = EnsureDeleted(operation); // Read the CA. byte[] caCertificateBytes = Convert.FromBase64String(CaPublicKeyBase64); X509Certificate2 caCertificate = new X509Certificate2(caCertificateBytes); // Read CA private key since getting it from caCertificate above throws. AsymmetricCipherKeyPair caPrivateKey; using (StringReader caPrivateKeyReader = new StringReader(CaPrivateKeyPem)) { Org.BouncyCastle.OpenSsl.PemReader reader = new Org.BouncyCastle.OpenSsl.PemReader(caPrivateKeyReader); caPrivateKey = (AsymmetricCipherKeyPair)reader.ReadObject(); } // Read the CSR. Pkcs10CertificationRequest csr = new Pkcs10CertificationRequest(operation.Properties.Csr); CertificationRequestInfo csrInfo = csr.GetCertificationRequestInfo(); // Parse the issuer subject name. Hashtable oidLookup = new Hashtable(X509Name.DefaultLookup) { { "s", new DerObjectIdentifier("2.5.4.8") }, }; X509Name issuerName = new X509Name(true, oidLookup, caCertificate.Subject); // Sign the request. X509V3CertificateGenerator generator = new X509V3CertificateGenerator(); generator.SetIssuerDN(issuerName); generator.SetSerialNumber(BigInteger.One); generator.SetNotBefore(DateTime.Now); generator.SetNotAfter(DateTime.Now.AddDays(1)); generator.SetSubjectDN(csrInfo.Subject); generator.SetPublicKey(csr.GetPublicKey()); Asn1SignatureFactory signatureFactory = new Asn1SignatureFactory("SHA256WITHRSA", caPrivateKey.Private); X509Certificate serverSignedPublicKey = generator.Generate(signatureFactory); // Merge the certificate chain. MergeCertificateOptions options = new MergeCertificateOptions(serverCertificateName, new[] { serverSignedPublicKey.GetEncoded(), caCertificateBytes }); KeyVaultCertificateWithPolicy mergedServerCertificate = await Client.MergeCertificateAsync(options); X509Certificate2 serverCertificate = new X509Certificate2(mergedServerCertificate.Cer); Assert.AreEqual(csrInfo.Subject.ToString(), serverCertificate.Subject); Assert.AreEqual(serverCertificateName, mergedServerCertificate.Name); KeyVaultCertificateWithPolicy completedServerCertificate = await operation.WaitForCompletionAsync(DefaultCertificateOperationPollingInterval, default); Assert.AreEqual(mergedServerCertificate.Name, completedServerCertificate.Name); CollectionAssert.AreEqual(mergedServerCertificate.Cer, completedServerCertificate.Cer); }
private X509Certificate MakeCertificate(AsymmetricCipherKeyPair subjectKeyPair, X509Name certificateSubject, AsymmetricCipherKeyPair rootKeyPair, X509Name rootSubject, bool isRootCertificate, bool addAuthorityKeyIdentifier) { X509Certificate x509Certificate; try { AsymmetricKeyParameter @public = subjectKeyPair.Public; AsymmetricKeyParameter @private = rootKeyPair.Private; AsymmetricKeyParameter asymmetricKeyParameter = rootKeyPair.Public; X509V3CertificateGenerator x509V3CertificateGenerator = new X509V3CertificateGenerator(); x509V3CertificateGenerator.Reset(); if (this.SerialNumber != -9223372036854775808L) { x509V3CertificateGenerator.SetSerialNumber(new BigInteger(this.SerialNumber.ToString())); } else { DateTime now = DateTime.Now; x509V3CertificateGenerator.SetSerialNumber(new BigInteger(128, new Random(now.Millisecond + Environment.TickCount))); } x509V3CertificateGenerator.SetIssuerDN(rootSubject); x509V3CertificateGenerator.SetNotBefore(this.ValidFrom.ToUniversalTime()); x509V3CertificateGenerator.SetNotAfter(this.ValidTo.ToUniversalTime()); x509V3CertificateGenerator.SetSubjectDN(certificateSubject); x509V3CertificateGenerator.SetPublicKey(@public); x509V3CertificateGenerator.SetSignatureAlgorithm(string.Concat(this.SignatureAlgorithm.ToString(), "Encryption")); int extensionType = 0; Asn1EncodableVector asn1EncodableVectors = new Asn1EncodableVector(new Asn1Encodable[0]); foreach (ExtensionInfo extension in this.Extensions.extensionInfo) { if (!extension.ExtendedKeyUsage) { extensionType |= (int)extension.ExtensionType; } if (!extension.ExtendedKeyUsage) { continue; } asn1EncodableVectors.Add(new Asn1Encodable[] { (Asn1Encodable)extension.ExtensionType }); } bool keyUsageIsCritical = this.Extensions.KeyUsageIsCritical; if (isRootCertificate) { x509V3CertificateGenerator.AddExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(true)); extensionType |= 6; keyUsageIsCritical = true; } if (extensionType != 0) { x509V3CertificateGenerator.AddExtension(X509Extensions.KeyUsage, keyUsageIsCritical, new KeyUsage(extensionType)); } if (asn1EncodableVectors.Count > 0) { x509V3CertificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage, this.Extensions.EnhancedKeyUsageIsCritical, ExtendedKeyUsage.GetInstance(new DerSequence(asn1EncodableVectors))); } x509V3CertificateGenerator.AddExtension(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(@public))); if (addAuthorityKeyIdentifier) { x509V3CertificateGenerator.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(asymmetricKeyParameter))); } X509Certificate x509Certificate1 = x509V3CertificateGenerator.Generate(@private, this.GetSecureRandom()); x509Certificate1.Verify(asymmetricKeyParameter); x509Certificate = x509Certificate1; } catch { throw; } return(x509Certificate); }
public void TestCreationDSA() { IBigInteger DSAParaG = new BigInteger(Base64.Decode("AL0fxOTq10OHFbCf8YldyGembqEu08EDVzxyLL29Zn/t4It661YNol1rnhPIs+cirw+yf9zeCe+KL1IbZ/qIMZM=")); IBigInteger DSAParaP = new BigInteger(Base64.Decode("AM2b/UeQA+ovv3dL05wlDHEKJ+qhnJBsRT5OB9WuyRC830G79y0R8wuq8jyIYWCYcTn1TeqVPWqiTv6oAoiEeOs=")); IBigInteger DSAParaQ = new BigInteger(Base64.Decode("AIlJT7mcKL6SUBMmvm24zX1EvjNx")); IBigInteger DSAPublicY = new BigInteger(Base64.Decode("TtWy2GuT9yGBWOHi1/EpCDa/bWJCk2+yAdr56rAcqP0eHGkMnA9s9GJD2nGU8sFjNHm55swpn6JQb8q0agrCfw==")); IBigInteger DsaPrivateX = new BigInteger(Base64.Decode("MMpBAxNlv7eYfxLTZ2BItJeD31A=")); DsaParameters para = new DsaParameters(DSAParaP, DSAParaQ, DSAParaG); DsaPrivateKeyParameters dsaPriv = new DsaPrivateKeyParameters(DsaPrivateX, para); DsaPublicKeyParameters dsaPub = new DsaPublicKeyParameters(DSAPublicY, para); IDictionary attrs = new Hashtable(); attrs[X509Name.C] = "AU"; attrs[X509Name.O] = "The Legion of the Bouncy Castle"; attrs[X509Name.L] = "Melbourne"; attrs[X509Name.ST] = "Victoria"; attrs[X509Name.E] = "*****@*****.**"; IList ord = new ArrayList(); ord.Add(X509Name.C); ord.Add(X509Name.O); ord.Add(X509Name.L); ord.Add(X509Name.ST); ord.Add(X509Name.E); IList values = new ArrayList(); values.Add("AU"); values.Add("The Legion of the Bouncy Castle"); values.Add("Melbourne"); values.Add("Victoria"); values.Add("*****@*****.**"); X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.SetSerialNumber(BigInteger.One); certGen.SetIssuerDN(new X509Name(ord, attrs)); certGen.SetNotBefore(DateTime.UtcNow.AddDays(-1)); certGen.SetNotAfter(DateTime.UtcNow.AddDays(1)); certGen.SetSubjectDN(new X509Name(ord, attrs)); certGen.SetPublicKey(dsaPub); certGen.SetSignatureAlgorithm("SHA1WITHDSA"); X509Certificate cert = certGen.Generate(dsaPriv); // Assert.IsTrue((cert.IsValidNow && cert.Verify(dsaPub)), "Certificate failed to be valid (DSA Test)"); cert.CheckValidity(); cert.Verify(dsaPub); ISet dummySet = cert.GetNonCriticalExtensionOids(); if (dummySet != null) { foreach (string key in dummySet) { Console.WriteLine("\t{0}:\t{1}", key); } } Console.WriteLine(); dummySet = cert.GetNonCriticalExtensionOids(); if (dummySet != null) { foreach (string key in dummySet) { Console.WriteLine("\t{0}:\t{1}", key); } } Console.WriteLine(); }
public static X509Certificate2 GenerateSelfSignedCertificate(X509Name issuer, X509Name subject, AsymmetricKeyParameter issuerPrivKey) { const int keyStrength = 2048; //generate random numbers CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator(); SecureRandom random = new SecureRandom(randomGenerator); ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA256WITHRSA", issuerPrivKey, random); //the certificate generator X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator(); certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage.Id, true, new ExtendedKeyUsage(KeyPurposeID.IdKPServerAuth)); //serial number BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(long.MaxValue), random); certificateGenerator.SetSerialNumber(serialNumber); // Issuer and Subject Name //X509Name subjectDN = new X509Name("CN=" + subjectName); //X509Name issuerDN = new X509Name("CN=" + issuerName); certificateGenerator.SetIssuerDN(issuer); certificateGenerator.SetSubjectDN(subject); //valid For DateTime notBefore = DateTime.Now.AddDays(-1); DateTime notAfter = notBefore.AddYears(2); certificateGenerator.SetNotBefore(notBefore); certificateGenerator.SetNotAfter(notAfter); //Subject Public Key var keyGenerationParameters = new KeyGenerationParameters(random, keyStrength); var keyPairGenerator = new RsaKeyPairGenerator(); keyPairGenerator.Init(keyGenerationParameters); var subjectKeyPair = keyPairGenerator.GenerateKeyPair(); certificateGenerator.SetPublicKey(subjectKeyPair.Public); //selfSign certificate Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(signatureFactory); //var dotNetPrivateKey = ToDotNetKey((RsaPrivateCrtKeyParameters)subjectKeyPair.Private); //merge into X509Certificate2 var certificate2 = new X509Certificate2(DotNetUtilities.ToX509Certificate(certificate)) { FriendlyName = "fulu sso", //设置友好名称 }; certificate2 = certificate2.CopyWithPrivateKey(DotNetUtilities.ToRSA((RsaPrivateCrtKeyParameters)subjectKeyPair.Private)); certificate2.FriendlyName = "fulu sso"; var bytes2 = certificate2.Export(X509ContentType.Pfx, "123456"); using (var fs = new FileStream("mypfx2.pfx", FileMode.Create)) { fs.Write(bytes2, 0, bytes2.Length); } //var x509 = new X509Certificate2(DotNetUtilities.ToX509Certificate(certificate)) //{ // PrivateKey = dotNetPrivateKey, // FriendlyName = "fulu sso" //}; return(certificate2); }
public void TestCreationRSA() { IBigInteger rsaPubMod = new BigInteger(Base64.Decode("AIASoe2PQb1IP7bTyC9usjHP7FvnUMVpKW49iuFtrw/dMpYlsMMoIU2jupfifDpdFxIktSB4P+6Ymg5WjvHKTIrvQ7SR4zV4jaPTu56Ys0pZ9EDA6gb3HLjtU+8Bb1mfWM+yjKxcPDuFjwEtjGlPHg1Vq+CA9HNcMSKNn2+tW6qt")); IBigInteger rsaPubExp = new BigInteger(Base64.Decode("EQ==")); IBigInteger rsaPrivMod = new BigInteger(Base64.Decode("AIASoe2PQb1IP7bTyC9usjHP7FvnUMVpKW49iuFtrw/dMpYlsMMoIU2jupfifDpdFxIktSB4P+6Ymg5WjvHKTIrvQ7SR4zV4jaPTu56Ys0pZ9EDA6gb3HLjtU+8Bb1mfWM+yjKxcPDuFjwEtjGlPHg1Vq+CA9HNcMSKNn2+tW6qt")); IBigInteger rsaPrivDP = new BigInteger(Base64.Decode("JXzfzG5v+HtLJIZqYMUefJfFLu8DPuJGaLD6lI3cZ0babWZ/oPGoJa5iHpX4Ul/7l3s1PFsuy1GhzCdOdlfRcQ==")); IBigInteger rsaPrivDQ = new BigInteger(Base64.Decode("YNdJhw3cn0gBoVmMIFRZzflPDNthBiWy/dUMSRfJCxoZjSnr1gysZHK01HteV1YYNGcwPdr3j4FbOfri5c6DUQ==")); IBigInteger rsaPrivExp = new BigInteger(Base64.Decode("DxFAOhDajr00rBjqX+7nyZ/9sHWRCCp9WEN5wCsFiWVRPtdB+NeLcou7mWXwf1Y+8xNgmmh//fPV45G2dsyBeZbXeJwB7bzx9NMEAfedchyOwjR8PYdjK3NpTLKtZlEJ6Jkh4QihrXpZMO4fKZWUm9bid3+lmiq43FwW+Hof8/E=")); IBigInteger rsaPrivP = new BigInteger(Base64.Decode("AJ9StyTVW+AL/1s7RBtFwZGFBgd3zctBqzzwKPda6LbtIFDznmwDCqAlIQH9X14X7UPLokCDhuAa76OnDXb1OiE=")); IBigInteger rsaPrivQ = new BigInteger(Base64.Decode("AM3JfD79dNJ5A3beScSzPtWxx/tSLi0QHFtkuhtSizeXdkv5FSba7lVzwEOGKHmW829bRoNxThDy4ds1IihW1w0=")); IBigInteger rsaPrivQinv = new BigInteger(Base64.Decode("Lt0g7wrsNsQxuDdB8q/rH8fSFeBXMGLtCIqfOec1j7FEIuYA/ACiRDgXkHa0WgN7nLXSjHoy630wC5Toq8vvUg==")); RsaKeyParameters rsaPublic = new RsaKeyParameters(false, rsaPubMod, rsaPubExp); RsaPrivateCrtKeyParameters rsaPrivate = new RsaPrivateCrtKeyParameters(rsaPrivMod, rsaPubExp, rsaPrivExp, rsaPrivP, rsaPrivQ, rsaPrivDP, rsaPrivDQ, rsaPrivQinv); IDictionary attrs = new Hashtable(); attrs[X509Name.C] = "AU"; attrs[X509Name.O] = "The Legion of the Bouncy Castle"; attrs[X509Name.L] = "Melbourne"; attrs[X509Name.ST] = "Victoria"; attrs[X509Name.E] = "*****@*****.**"; IList ord = new ArrayList(); ord.Add(X509Name.C); ord.Add(X509Name.O); ord.Add(X509Name.L); ord.Add(X509Name.ST); ord.Add(X509Name.E); IList values = new ArrayList(); values.Add("AU"); values.Add("The Legion of the Bouncy Castle"); values.Add("Melbourne"); values.Add("Victoria"); values.Add("*****@*****.**"); X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.SetSerialNumber(BigInteger.One); certGen.SetIssuerDN(new X509Name(ord, attrs)); certGen.SetNotBefore(DateTime.UtcNow.AddDays(-1)); certGen.SetNotAfter(DateTime.UtcNow.AddDays(1)); certGen.SetSubjectDN(new X509Name(ord, attrs)); certGen.SetPublicKey(rsaPublic); certGen.SetSignatureAlgorithm("MD5WithRSAEncryption"); X509Certificate cert = certGen.Generate(rsaPrivate); // Assert.IsTrue((cert.IsValidNow && cert.Verify(rsaPublic)),"Certificate failed to be valid (RSA)"); cert.CheckValidity(); cert.Verify(rsaPublic); //Console.WriteLine(ASN1Dump.DumpAsString(cert.ToAsn1Object())); ISet dummySet = cert.GetNonCriticalExtensionOids(); if (dummySet != null) { foreach (string key in dummySet) { Console.WriteLine("\t{0}:\t{1}", key); } } Console.WriteLine(); dummySet = cert.GetNonCriticalExtensionOids(); if (dummySet != null) { foreach (string key in dummySet) { Console.WriteLine("\t{0}:\t{1}", key); } } Console.WriteLine(); }
public static (Certificate crtificate, AsymmetricKeyParameter privateKey) CreateSelfSignedTlsCert( string subjectName, string issuerName, AsymmetricKeyParameter issuerPrivateKey) { const int keyStrength = DEFAULT_KEY_SIZE; if (issuerPrivateKey == null) { issuerPrivateKey = CreatePrivateKeyResource(issuerName); } // Generating Random Numbers var randomGenerator = new CryptoApiRandomGenerator(); var random = new SecureRandom(randomGenerator); ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA256WITHRSA", issuerPrivateKey, random); // The Certificate Generator var certificateGenerator = new X509V3CertificateGenerator(); certificateGenerator.AddExtension(X509Extensions.SubjectAlternativeName, false, new GeneralNames(new GeneralName[] { new GeneralName(GeneralName.DnsName, "localhost"), new GeneralName(GeneralName.DnsName, "127.0.0.1") })); certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage, true, new ExtendedKeyUsage(new List <DerObjectIdentifier>() { new DerObjectIdentifier("1.3.6.1.5.5.7.3.1") })); // Serial Number var serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random); certificateGenerator.SetSerialNumber(serialNumber); // 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(70); certificateGenerator.SetNotBefore(notBefore); certificateGenerator.SetNotAfter(notAfter); // Subject Public Key var keyGenerationParameters = new KeyGenerationParameters(random, keyStrength); var keyPairGenerator = new RsaKeyPairGenerator(); keyPairGenerator.Init(keyGenerationParameters); var subjectKeyPair = keyPairGenerator.GenerateKeyPair(); certificateGenerator.SetPublicKey(subjectKeyPair.Public); // self sign certificate var certificate = certificateGenerator.Generate(signatureFactory); var chain = new X509CertificateStructure[] { X509CertificateStructure.GetInstance(certificate.GetEncoded()) }; var tlsCertificate = new Certificate(chain); return(tlsCertificate, subjectKeyPair.Private); }