/// <summary> /// Generates a user certificate /// </summary> /// <param name="subject">X509Name subject name </param> /// <param name="issuer">X509Name issuer name</param> /// <param name="iValidity">validity in days</param> /// <param name="publicKey">publickey</param> /// <param name="privateKey">private key of the issuer</param> /// <param name="signatureType">signature type</param> /// <param name="keyusages">keyusages, <see>Org.BouncyCastle.Asn1.X509.KeyUsage</see></param> /// <param name="extendedKeyUsages">extendedKeyUsages <see>Org.BouncyCastle.Asn1.X509.KeyPurposeID</see></param> /// <returns>brand new generated X509Certificate</returns> public static X509Certificate GenerateUserCertificate(X509Name subject, X509Name issuer, int iValidity, AsymmetricKeyParameter publicKey, AsymmetricKeyParameter privateKey, String signatureType, int keyusages, ExtendedKeyUsage extendedKeyUsages) { return GenerateCertificate(subject, issuer, iValidity, publicKey, privateKey, signatureType, keyusages, extendedKeyUsages, false, 0); }
/// <summary> /// Generates a CA certificate. /// </summary> /// <param name="subject">X509Name subject name </param> /// <param name="iValidity">validity in days</param> /// <param name="publicKey">publickey</param> /// <param name="privateKey">private key of the issuer</param> /// <param name="signatureType">signature type</param> /// <param name="keyusages">keyusages, <see>Org.BouncyCastle.Asn1.X509.KeyUsage</see></param> /// <param name="extendedKeyUsages">extendedKeyUsages <see>Org.BouncyCastle.Asn1.X509.KeyPurposeID</see></param> /// <param name="pathLenConstraint"> </param> /// <returns>brand new generated X509Certificate</returns> public static X509Certificate GenerateCACertificate(X509Name subject, int iValidity, AsymmetricKeyParameter publicKey, AsymmetricKeyParameter privateKey, String signatureType, int keyusages, ExtendedKeyUsage extendedKeyUsages, int pathLenConstraint) { return GenerateCertificate(subject, subject, iValidity, publicKey, privateKey, signatureType, keyusages, extendedKeyUsages, true, pathLenConstraint); }
/// <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, string exportDirectory = null) { // 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(10000); // create the individual store and set two entries for cert and key var store = new Pkcs12Store(); store.SetCertificateEntry("Created by Fluent Management", entry); store.SetKeyEntry("Created by Fluent Management", keyEntry, new[] { entry }); store.Save(stream, userPassword.ToCharArray(), new SecureRandom()); // Create the equivalent C# representation var cert = new X509Certificate2(stream.GetBuffer(), userPassword, X509KeyStorageFlags.Exportable); // set up the PEM writer too if (exportDirectory != null) { var textWriter = new StringWriter(); var pemWriter = new PemWriter(textWriter); pemWriter.WriteObject(cerKp.Private, "DESEDE", userPassword.ToCharArray(), new SecureRandom()); pemWriter.Writer.Flush(); string privateKeyPem = textWriter.ToString(); using (var writer = new StreamWriter(Path.Combine(exportDirectory, cert.Thumbprint + ".pem"))) { writer.WriteLine(privateKeyPem); } // also export the certs - first the .pfx byte[] privateKeyBytes = cert.Export(X509ContentType.Pfx, userPassword); using (var writer = new FileStream(Path.Combine(exportDirectory, cert.Thumbprint + ".pfx"), FileMode.OpenOrCreate, FileAccess.Write)) { writer.Write(privateKeyBytes, 0, privateKeyBytes.Length); } // also export the certs - then the .cer byte[] publicKeyBytes = cert.Export(X509ContentType.Cert); using (var writer = new FileStream(Path.Combine(exportDirectory, cert.Thumbprint + ".cer"), FileMode.OpenOrCreate, FileAccess.Write)) { writer.Write(publicKeyBytes, 0, publicKeyBytes.Length); } } // if specified then this add this certificate to the store if (addtoStore) AddToMyStore(cert); return cert; }
/// <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; }
private static X509Certificate GenerateCertificate(X509Name subject, X509Name issuer, int iValidity, AsymmetricKeyParameter publicKey, AsymmetricKeyParameter privateKey, String signatureType, int keyusages, ExtendedKeyUsage extendedKeyUsages, bool isCA, int pathLenConstraint) { // Get an X509 Version 1 Certificate generator var certGen = new X509V3CertificateGenerator(); // Load the generator with generation parameters // Set the issuer distinguished name certGen.SetIssuerDN(issuer); // Valid before and after dates now to iValidity days in the future certGen.SetNotBefore(DateTime.Now); certGen.SetNotAfter(DateTime.Now.AddDays(iValidity)); // Set the subject distinguished name (same as issuer for our purposes) certGen.SetSubjectDN(subject); // Set the public key certGen.SetPublicKey(publicKey); // Set the algorithm certGen.SetSignatureAlgorithm(signatureType); // Set the serial number //read the serial number String serial = Repository.Instance.ReadSerialNumber(); var biSerial = new BigInteger(serial, Repository.SerialNumberRadix); certGen.SetSerialNumber(biSerial); certGen.AddExtension(X509Extensions.KeyUsage, false, new KeyUsage(keyusages)); if (extendedKeyUsages != null) certGen.AddExtension(X509Extensions.ExtendedKeyUsage, false, extendedKeyUsages); if (isCA) certGen.AddExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(pathLenConstraint)); try { // Generate an X.509 certificate, based on the current issuer and subject return certGen.Generate(privateKey); } // Something went wrong //catch (GeneralSecurityException ex) //{ // throw new CryptoException(ex.Message,ex); //} finally { Repository.Instance.IncrementSerial(); } }