private static CX509ExtensionAlternativeNames GetSAN(string cn) { var san = new CX509ExtensionAlternativeNames(); var alternativeNames = new CAlternativeNames(); foreach (var item in cn.Split(',')) { var alternativeName = new CAlternativeName(); alternativeName.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME, item); alternativeNames.Add(alternativeName); } san.InitializeEncode(alternativeNames); return(san); }
private CX509Extension GetQualifiedSan(List <string> san) { CAlternativeNames altNames = new CAlternativeNames(); CObjectId sanOid = new CObjectId(); CX509ExtensionAlternativeNames encodedAltNames = new CX509ExtensionAlternativeNames(); sanOid.InitializeFromValue("2.5.29.17"); foreach (string strAltName in san) { CAlternativeName altName = (CAlternativeName)Activator.CreateInstance(Type.GetTypeFromProgID("X509Enrollment.CAlternativeName")); altName.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME, strAltName); altNames.Add(altName); altName = null; } encodedAltNames.InitializeEncode(altNames); return((CX509Extension)encodedAltNames); }
/// <summary> /// Create a certificate signing request. /// </summary> /// <param name="subjectName">The subject name of the certificate.</param> /// <param name="keyLength">Size of the key in bits.</param> /// <param name="durationYears">Duration of the certificate, specified in years.</param> /// <param name="oids">Collection of OIDs identifying certificate usage.</param> public static CX509CertificateRequestCertificate CreateCertificateSigningRequest(string subjectName, int keyLength, int durationYears, List <string> oids) { // Prepend the subject name with CN= if it doesn't begin with CN=, E=, etc.. if (subjectName.IndexOf("=") < 0) { subjectName = "CN=" + subjectName; } // Generate a distinguished name. CX500DistinguishedName distinguishedName = new CX500DistinguishedName(); distinguishedName.Encode(subjectName, X500NameFlags.XCN_CERT_NAME_STR_NONE); // Generate a private key. CX509PrivateKey privateKey = new CX509PrivateKey(); privateKey.ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG; privateKey.KeySpec = X509KeySpec.XCN_AT_SIGNATURE; privateKey.Length = keyLength; privateKey.MachineContext = true; privateKey.ProviderName = "Microsoft Enhanced Cryptographic Provider v1.0"; privateKey.Create(); // Use the SHA-512 hashing algorithm. CObjectId hashAlgorithm = new CObjectId(); hashAlgorithm.InitializeFromAlgorithmName(ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID, ObjectIdPublicKeyFlags.XCN_CRYPT_OID_INFO_PUBKEY_ANY, AlgorithmFlags.AlgorithmFlagsNone, "SHA512"); // Load the OIDs passed in and specify enhanced key usages. CObjectIds oidCollection = new CObjectIds(); foreach (string oidID in oids) { CObjectId oid = new CObjectId(); oid.InitializeFromValue(oidID); oidCollection.Add(oid); } CX509ExtensionKeyUsage keyUsage = new CX509ExtensionKeyUsage(); keyUsage.InitializeEncode(CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_DIGITAL_SIGNATURE_KEY_USAGE | CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_KEY_ENCIPHERMENT_KEY_USAGE); CX509ExtensionEnhancedKeyUsage enhancedKeyUsages = new CX509ExtensionEnhancedKeyUsage(); enhancedKeyUsages.InitializeEncode(oidCollection); string sanSubjectName = subjectName.Substring(subjectName.IndexOf("=") + 1); CAlternativeName sanAlternateName = new CAlternativeName(); sanAlternateName.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_RFC822_NAME, sanSubjectName); CAlternativeNames sanAlternativeNames = new CAlternativeNames(); sanAlternativeNames.Add(sanAlternateName); CX509ExtensionAlternativeNames alternativeNamesExtension = new CX509ExtensionAlternativeNames(); alternativeNamesExtension.InitializeEncode(sanAlternativeNames); CX509ExtensionSmimeCapabilities smimeCapabilities = new CX509ExtensionSmimeCapabilities(); smimeCapabilities.SmimeCapabilities.AddAvailableSmimeCapabilities(false); // Create the self-signing request. CX509CertificateRequestCertificate cert = new CX509CertificateRequestCertificate(); cert.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextMachine, privateKey, ""); cert.Subject = distinguishedName; cert.Issuer = distinguishedName; cert.NotBefore = DateTime.Now; cert.NotAfter = DateTime.Now.AddYears(1); cert.X509Extensions.Add((CX509Extension)keyUsage); cert.X509Extensions.Add((CX509Extension)enhancedKeyUsages); cert.X509Extensions.Add((CX509Extension)alternativeNamesExtension); cert.X509Extensions.Add((CX509Extension)smimeCapabilities); cert.HashAlgorithm = hashAlgorithm; cert.Encode(); return(cert); }
private static StoreName store = StoreName.My; // Store as a personal certificate private static X509Certificate2 CreateSelfSignedCertificate(string Operator, string SiteId, int SeqNo, bool isServerCert, string SAN) { // Create a custom subject name & friendly name string distName = $"CN={FriendlyName.ToLower()}_{SiteId}_{SeqNo}, OU={Operator}_{SiteId}, O={Operator}, C=GB"; // create DN for subject and issuer // var dn = new X500DistinguishedName(distName); // dn.Encode(distName, X500NameFlags.XCN_CERT_NAME_STR_NONE); var dn = new CX500DistinguishedName(); dn.Encode(distName, X500NameFlags.XCN_CERT_NAME_STR_NONE); // create a new private key for the certificate //CX509PrivateKey privateKey = new CX509PrivateKey(); //var privateKey = new CX509PrivateKey(); var typeName = "X509Enrollment.CX509PrivateKey"; var type = Type.GetTypeFromProgID(typeName); if (type == null) { throw new Exception(typeName + " is not available on your system: 0x80040154 (REGDB_E_CLASSNOTREG)"); } var privateKey = Activator.CreateInstance(type) as IX509PrivateKey; if (privateKey == null) { throw new Exception("Your certlib does not know an implementation of " + typeName + " (in HKLM:\\SOFTWARE\\Classes\\Interface\\)!"); } privateKey.ProviderName = "Microsoft Base Cryptographic Provider v1.0"; privateKey.MachineContext = true; privateKey.Length = 2048; privateKey.KeySpec = X509KeySpec.XCN_AT_SIGNATURE; // use is not limited // privateKey.ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG; privateKey.ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_FLAG; privateKey.Create(); // Use the stronger SHA512 hashing algorithm var hashobj = new CObjectId(); hashobj.InitializeFromAlgorithmName(ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID, ObjectIdPublicKeyFlags.XCN_CRYPT_OID_INFO_PUBKEY_ANY, AlgorithmFlags.AlgorithmFlagsNone, "SHA512"); // add extended key usage if you want - look at MSDN for a list of possible OIDs var oid = new CObjectId(); // oid.InitializeFromValue("1.3.6.1.5.5.7.3.1"); // SSL server if (isServerCert) { oid.InitializeFromValue("1.3.6.1.5.5.7.3.1"); // SSL Server } else { oid.InitializeFromValue("1.3.6.1.5.5.7.3.2"); // SSL client } var oidlist = new CObjectIds(); oidlist.Add(oid); var eku = new CX509ExtensionEnhancedKeyUsage(); eku.InitializeEncode(oidlist); // Create the self signing request var cert = new CX509CertificateRequestCertificate(); cert.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextMachine, privateKey, ""); if (!string.IsNullOrEmpty(SAN)) { CAlternativeName objRfc822Name = new CAlternativeName(); CAlternativeNames objAlternativeNames = new CAlternativeNames(); CX509ExtensionAlternativeNames objExtensionAlternativeNames = new CX509ExtensionAlternativeNames(); // Set Alternative RFC822 Name objRfc822Name.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME, SAN); // Set Alternative Names objAlternativeNames.Add(objRfc822Name); objExtensionAlternativeNames.InitializeEncode(objAlternativeNames); cert.X509Extensions.Add((CX509Extension)objExtensionAlternativeNames); } cert.Subject = dn; cert.Issuer = dn; // the issuer and the subject are the same cert.NotBefore = DateTime.Today; cert.NotAfter = DateTime.Today.AddYears(10); // expire in 10 years time cert.X509Extensions.Add((CX509Extension)eku); // add the EKU cert.HashAlgorithm = hashobj; // Specify the hashing algorithm cert.Encode(); // encode the certificate // Do the final enrollment process var enroll = new CX509Enrollment(); enroll.InitializeFromRequest(cert); // load the certificate enroll.CertificateFriendlyName = FriendlyName; // Optional: add a friendly name string csr = enroll.CreateRequest(); // Output the request in base64 // and install it back as the response enroll.InstallResponse(InstallResponseRestrictionFlags.AllowUntrustedCertificate, csr, EncodingType.XCN_CRYPT_STRING_BASE64, ""); // no password // output a base64 encoded PKCS#12 so we can import it back to the .Net security classes var base64encoded = enroll.CreatePFX("", // no password, this is for internal consumption PFXExportOptions.PFXExportChainWithRoot); // instantiate the target class with the PKCS#12 data (and the empty password) X509Certificate2 newCert = new X509Certificate2(System.Convert.FromBase64String(base64encoded), "", // mark the private key as exportable (this is usually what you want to do) System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.Exportable // Ensure the machine key is created and retained // http://stackoverflow.com/questions/425688/how-to-set-read-permission-on-the-private-key-file-of-x-509-certificate-from-ne | X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet); return(newCert); }
private static string CreateCertContent(string cn, TimeSpan expirationLength, string pwd) { string base64encoded = string.Empty; var dn = new CERTENROLLLib.CX500DistinguishedName(); dn.Encode("CN=" + cn, X500NameFlags.XCN_CERT_NAME_STR_NONE); CX509PrivateKey privateKey = new CX509PrivateKey(); privateKey.ProviderName = "Microsoft Strong Cryptographic Provider"; privateKey.Length = 2048; privateKey.KeySpec = X509KeySpec.XCN_AT_KEYEXCHANGE; privateKey.KeyUsage = X509PrivateKeyUsageFlags.XCN_NCRYPT_ALLOW_DECRYPT_FLAG | X509PrivateKeyUsageFlags.XCN_NCRYPT_ALLOW_KEY_AGREEMENT_FLAG; privateKey.MachineContext = true; privateKey.ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG; privateKey.Create(); // Use the stronger SHA512 hashing algorithm var hashobj = new CObjectId(); hashobj.InitializeFromAlgorithmName(ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID, ObjectIdPublicKeyFlags.XCN_CRYPT_OID_INFO_PUBKEY_ANY, AlgorithmFlags.AlgorithmFlagsNone, "SHA512"); // Create the self signing request var cert = new CX509CertificateRequestCertificate(); cert.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextMachine, privateKey, ""); cert.Subject = dn; cert.Issuer = dn; // the issuer and the subject are the same cert.NotBefore = DateTime.Now.Date; var objExtensionAlternativeNames = new CX509ExtensionAlternativeNames(); { var altNames = new CAlternativeNames(); //var dnsHostname = new CAlternativeName(); //dnsHostname.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME, Environment.MachineName); //altNames.Add(dnsHostname); //foreach (var ipAddress in Dns.GetHostAddresses(Dns.GetHostName())) //{ // if ((ipAddress.AddressFamily == AddressFamily.InterNetwork || // ipAddress.AddressFamily == AddressFamily.InterNetworkV6) && !IPAddress.IsLoopback(ipAddress)) // { // var dns = new CAlternativeName(); // dns.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME, ipAddress.ToString()); // altNames.Add(dns); // } //} var dns1 = new CAlternativeName(); dns1.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME, "localhost"); altNames.Add(dns1); objExtensionAlternativeNames.InitializeEncode(altNames); } cert.X509Extensions.Add((CX509Extension)objExtensionAlternativeNames); // this cert expires immediately. Change to whatever makes sense for you cert.NotAfter = cert.NotBefore + expirationLength; cert.HashAlgorithm = hashobj; // Specify the hashing algorithm cert.Encode(); // encode the certificate // Do the final enrollment process var enroll = new CX509Enrollment(); enroll.InitializeFromRequest(cert); // load the certificate enroll.CertificateFriendlyName = cn; // Optional: add a friendly name string csr = enroll.CreateRequest(); // Output the request in base64 // and install it back as the response enroll.InstallResponse(InstallResponseRestrictionFlags.AllowUntrustedCertificate, csr, EncodingType.XCN_CRYPT_STRING_BASE64, pwd); // no password // output a base64 encoded PKCS#12 so we can import it back to the .Net security classes base64encoded = enroll.CreatePFX(pwd, // no password, this is for internal consumption PFXExportOptions.PFXExportChainWithRoot); return(base64encoded); }
public static X509Certificate2 CreateCertificate(Certificate crt) { bool isCA = !crt.SignByCertificateAuthority; // create DN for subject and issuer var dn = new CX500DistinguishedName(); dn.Encode(GetEncodedDistinguishedName(crt), X500NameFlags.XCN_CERT_NAME_STR_NONE); // create a new private key for the certificate CX509PrivateKey privateKey = new CX509PrivateKey { ProviderName = "Microsoft Base Cryptographic Provider v1.0", MachineContext = crt.MachineContext, Length = crt.KeyLength, KeySpec = X509KeySpec.XCN_AT_SIGNATURE, // use is not limited ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG }; privateKey.Create(); var hashobj = new CObjectId(); hashobj.InitializeFromAlgorithmName(ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID, ObjectIdPublicKeyFlags.XCN_CRYPT_OID_INFO_PUBKEY_ANY, AlgorithmFlags.AlgorithmFlagsNone, crt.DigestAlgorithm); CERTENROLLLib.X509KeyUsageFlags x509KeyUsageFlags; CX509ExtensionBasicConstraints bc = new CX509ExtensionBasicConstraints(); if (isCA) { x509KeyUsageFlags = CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_DIGITAL_SIGNATURE_KEY_USAGE | CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_KEY_CERT_SIGN_KEY_USAGE | CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_CRL_SIGN_KEY_USAGE | CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_OFFLINE_CRL_SIGN_KEY_USAGE; bc.InitializeEncode(true, -1); bc.Critical = true; } else { x509KeyUsageFlags = CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_KEY_ENCIPHERMENT_KEY_USAGE | CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_DIGITAL_SIGNATURE_KEY_USAGE; if (crt.CertificateType == CertificateType.ClientCertificate) { x509KeyUsageFlags |= CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_NON_REPUDIATION_KEY_USAGE; } if (crt.CertificateType == CertificateType.ServerCertificate) { x509KeyUsageFlags |= CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_NON_REPUDIATION_KEY_USAGE; } bc.InitializeEncode(false, -1); bc.Critical = false; } CX509ExtensionKeyUsage keyUsage = new CX509ExtensionKeyUsage(); keyUsage.InitializeEncode(x509KeyUsageFlags); keyUsage.Critical = false; // SAN var canList = new List <CAlternativeName>(); foreach (var sanItem in crt.SANList) { if (!string.IsNullOrWhiteSpace(sanItem.Value)) { var can = new CAlternativeName(); switch (sanItem.Type) { case Certificate.SANType.DNS: can.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME, sanItem.Value); break; case Certificate.SANType.IP: can.InitializeFromRawData(AlternativeNameType.XCN_CERT_ALT_NAME_IP_ADDRESS, EncodingType.XCN_CRYPT_STRING_BASE64, Convert.ToBase64String(IPAddress.Parse(sanItem.Value).GetAddressBytes())); break; case Certificate.SANType.URI: can.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_URL, sanItem.Value); break; case Certificate.SANType.email: can.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_RFC822_NAME, sanItem.Value); break; } canList.Add(can); } } CX509ExtensionAlternativeNames san = null; if (canList.Any()) { san = new CX509ExtensionAlternativeNames(); var cans = new CAlternativeNames(); foreach (var item in canList) { cans.Add(item); } san.InitializeEncode(cans); } CX509ExtensionEnhancedKeyUsage eku = null; if (crt.CertificateType != CertificateType.None) { const string XCN_OID_PKIX_KP_SERVER_AUTH = "1.3.6.1.5.5.7.3.1"; const string XCN_OID_PKIX_KP_CLIENT_AUTH = "1.3.6.1.5.5.7.3.2"; var oid = new CObjectId(); if (crt.CertificateType == CertificateType.ServerCertificate) { oid.InitializeFromValue(XCN_OID_PKIX_KP_SERVER_AUTH); } if (crt.CertificateType == CertificateType.ClientCertificate) { oid.InitializeFromValue(XCN_OID_PKIX_KP_CLIENT_AUTH); } var oidlist = new CObjectIds(); oidlist.Add(oid); eku = new CX509ExtensionEnhancedKeyUsage(); eku.InitializeEncode(oidlist); } // Create the self signing request var cereq = new CX509CertificateRequestCertificate(); cereq.InitializeFromPrivateKey(crt.MachineContext ? X509CertificateEnrollmentContext.ContextMachine : X509CertificateEnrollmentContext.ContextUser, privateKey, ""); cereq.Subject = dn; cereq.Issuer = dn; cereq.NotBefore = DateTime.UtcNow.AddDays(-1); cereq.NotAfter = DateTime.UtcNow.AddDays(crt.Lifetime.Value); if (crt.SignByCertificateAuthority) { var issuer = MyCurrentUserX509Store.Certificates .Find(X509FindType.FindByThumbprint, crt.CertificateAuthority, false) .OfType <X509Certificate2>() .Where(c => c.HasPrivateKey).FirstOrDefault() ?? throw new Exception("Issuer not found: " + crt.CertificateAuthority); cereq.SignerCertificate = new CSignerCertificate(); cereq.SignerCertificate.Initialize(false, X509PrivateKeyVerify.VerifyNone, EncodingType.XCN_CRYPT_STRING_HEX, issuer.GetRawCertDataString()); cereq.Issuer = new CX500DistinguishedName(); cereq.Issuer.Encode(issuer.Subject, X500NameFlags.XCN_CERT_NAME_STR_NONE); } cereq.X509Extensions.Add((CX509Extension)keyUsage); if (eku != null) { cereq.X509Extensions.Add((CX509Extension)eku); // EnhancedKeyUsage } if (bc != null) { cereq.X509Extensions.Add((CX509Extension)bc); // ExtensionBasicConstraints } if (san != null) { cereq.X509Extensions.Add((CX509Extension)san); // SAN } cereq.HashAlgorithm = hashobj; // Specify the hashing algorithm cereq.Encode(); // encode the certificate // Do the final enrollment process var enroll = new CX509Enrollment(); enroll.InitializeFromRequest(cereq); // load the certificate //enroll.CertificateFriendlyName = subjectName; // Optional: add a friendly name string csr = enroll.CreateRequest(); // Output the request in base64 // and install it back as the response enroll.InstallResponse(InstallResponseRestrictionFlags.AllowUntrustedCertificate, csr, EncodingType.XCN_CRYPT_STRING_BASE64, ""); // no password // output a base64 encoded PKCS#12 so we can import it back to the .Net security classes var base64encoded = enroll.CreatePFX("", // no password, this is for internal consumption PFXExportOptions.PFXExportChainWithRoot); // instantiate the target class with the PKCS#12 data (and the empty password) var x509Certificate2 = new X509Certificate2( Convert.FromBase64String(base64encoded), "", X509KeyStorageFlags.Exportable); // mark the private key as exportable (this is usually what you want to do) if (isCA) { X509Store rootStore = null; try { rootStore = new X509Store(StoreName.Root, crt.MachineContext ? StoreLocation.LocalMachine : StoreLocation.CurrentUser); rootStore.Open(OpenFlags.ReadWrite); // install to CA store var crtPub = new X509Certificate2(x509Certificate2) { PrivateKey = null }; rootStore.Add(crtPub); crtPub.Reset(); } catch { // ignore when adding to trust root failed } finally { rootStore?.Close(); } } crt.Value = x509Certificate2; return(x509Certificate2); }
public static X509Certificate2 CreateCertificate(string certSubject, bool isCA) { string CAsubject = certSubject; CX500DistinguishedName dn = new CX500DistinguishedName(); dn.Encode("CN=" + CAsubject, X500NameFlags.XCN_CERT_NAME_STR_NONE); string strRfc822Name = certSubject; CAlternativeName objRfc822Name = new CAlternativeName(); CAlternativeNames objAlternativeNames = new CAlternativeNames(); CX509ExtensionAlternativeNames objExtensionAlternativeNames = new CX509ExtensionAlternativeNames(); // Set Alternative RFC822 Name objRfc822Name.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME, strRfc822Name); // Set Alternative Names objAlternativeNames.Add(objRfc822Name); objExtensionAlternativeNames.InitializeEncode(objAlternativeNames); //objPkcs10.X509Extensions.Add((CX509Extension)objExtensionAlternativeNames); //Issuer Property for cleanup string issuer = "__Interceptor_Trusted_Root"; CX500DistinguishedName issuerdn = new CX500DistinguishedName(); issuerdn.Encode("CN=" + issuer, X500NameFlags.XCN_CERT_NAME_STR_NONE); // Create a new Private Key CX509PrivateKey key = new CX509PrivateKey(); key.ProviderName = "Microsoft Enhanced RSA and AES Cryptographic Provider"; //"Microsoft Enhanced Cryptographic Provider v1.0" // Set CAcert to 1 to be used for Signature if (isCA) { key.KeySpec = X509KeySpec.XCN_AT_SIGNATURE; } else { key.KeySpec = X509KeySpec.XCN_AT_KEYEXCHANGE; } key.Length = 2048; key.MachineContext = true; key.Create(); // Create Attributes //var serverauthoid = new X509Enrollment.CObjectId(); CObjectId serverauthoid = new CObjectId(); serverauthoid.InitializeFromValue("1.3.6.1.5.5.7.3.1"); CObjectIds ekuoids = new CObjectIds(); ekuoids.Add(serverauthoid); CX509ExtensionEnhancedKeyUsage ekuext = new CX509ExtensionEnhancedKeyUsage(); ekuext.InitializeEncode(ekuoids); CX509CertificateRequestCertificate cert = new CX509CertificateRequestCertificate(); cert.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextMachine, key, ""); cert.Subject = dn; cert.Issuer = issuerdn; cert.NotBefore = (DateTime.Now).AddDays(-1); //Backup One day to Avoid Timing Issues cert.NotAfter = cert.NotBefore.AddDays(90); //Arbitrary... Change to persist longer... //Use Sha256 CObjectId hashAlgorithmObject = new CObjectId(); hashAlgorithmObject.InitializeFromAlgorithmName(ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID, 0, 0, "SHA256"); cert.HashAlgorithm = hashAlgorithmObject; cert.X509Extensions.Add((CX509Extension)ekuext); cert.X509Extensions.Add((CX509Extension)objExtensionAlternativeNames); //https://blogs.msdn.microsoft.com/alejacma/2011/11/07/how-to-add-subject-alternative-name-to-your-certificate-requests-c/ if (isCA) { CX509ExtensionBasicConstraints basicConst = new CX509ExtensionBasicConstraints(); basicConst.InitializeEncode(true, 1); cert.X509Extensions.Add((CX509Extension)basicConst); } else { var store = new X509Store(StoreName.My, StoreLocation.LocalMachine); store.Open(OpenFlags.ReadOnly); X509Certificate2Collection signer = store.Certificates.Find(X509FindType.FindBySubjectName, "__Interceptor_Trusted_Root", false); CSignerCertificate signerCertificate = new CSignerCertificate(); signerCertificate.Initialize(true, 0, EncodingType.XCN_CRYPT_STRING_HEX, signer[0].Thumbprint); cert.SignerCertificate = signerCertificate; } cert.Encode(); CX509Enrollment enrollment = new CX509Enrollment(); enrollment.InitializeFromRequest(cert); string certdata = enrollment.CreateRequest(0); enrollment.InstallResponse(InstallResponseRestrictionFlags.AllowUntrustedCertificate, certdata, 0, ""); if (isCA) { //Install CA Root Certificate X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine); store.Open(OpenFlags.ReadOnly); X509Certificate2Collection certList = store.Certificates.Find(X509FindType.FindBySubjectName, "__Interceptor_Trusted_Root", false); store.Close(); X509Store rootStore = new X509Store(StoreName.Root, StoreLocation.LocalMachine); rootStore.Open(OpenFlags.ReadWrite); X509Certificate2Collection rootcertList = rootStore.Certificates.Find(X509FindType.FindBySubjectName, "__Interceptor_Trusted_Root", false); rootStore.Add(certList[0]); rootStore.Close(); return(certList[0]); } else { //Return Per Domain Cert X509Store xstore = new X509Store(StoreName.My, StoreLocation.LocalMachine); xstore.Open(OpenFlags.ReadOnly); X509Certificate2Collection certList = xstore.Certificates.Find(X509FindType.FindBySubjectName, certSubject, false); xstore.Close(); return(certList[0]); } }
/// <summary> /// Create a certificate signing request. /// </summary> /// <param name="subjectName">The subject name of the certificate.</param> /// <param name="keyLength">Size of the key in bits.</param> /// <param name="durationYears">Duration of the certificate, specified in years.</param> /// <param name="oids">Collection of OIDs identifying certificate usage.</param> public static CX509CertificateRequestCertificate CreateCertificateSigningRequest(string subjectName, int keyLength, int durationYears, List<string> oids) { // Prepend the subject name with CN= if it doesn't begin with CN=, E=, etc.. if (subjectName.IndexOf("=") < 0) subjectName = "CN=" + subjectName; // Generate a distinguished name. CX500DistinguishedName distinguishedName = new CX500DistinguishedName(); distinguishedName.Encode(subjectName, X500NameFlags.XCN_CERT_NAME_STR_NONE); // Generate a private key. CX509PrivateKey privateKey = new CX509PrivateKey(); privateKey.ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG; privateKey.KeySpec = X509KeySpec.XCN_AT_SIGNATURE; privateKey.Length = keyLength; privateKey.MachineContext = true; privateKey.ProviderName = "Microsoft Enhanced Cryptographic Provider v1.0"; privateKey.Create(); // Use the SHA-512 hashing algorithm. CObjectId hashAlgorithm = new CObjectId(); hashAlgorithm.InitializeFromAlgorithmName(ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID, ObjectIdPublicKeyFlags.XCN_CRYPT_OID_INFO_PUBKEY_ANY, AlgorithmFlags.AlgorithmFlagsNone, "SHA512"); // Load the OIDs passed in and specify enhanced key usages. CObjectIds oidCollection = new CObjectIds(); foreach (string oidID in oids) { CObjectId oid = new CObjectId(); oid.InitializeFromValue(oidID); oidCollection.Add(oid); } CX509ExtensionKeyUsage keyUsage = new CX509ExtensionKeyUsage(); keyUsage.InitializeEncode(CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_DIGITAL_SIGNATURE_KEY_USAGE | CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_KEY_ENCIPHERMENT_KEY_USAGE); CX509ExtensionEnhancedKeyUsage enhancedKeyUsages = new CX509ExtensionEnhancedKeyUsage(); enhancedKeyUsages.InitializeEncode(oidCollection); string sanSubjectName = subjectName.Substring(subjectName.IndexOf("=") + 1); CAlternativeName sanAlternateName = new CAlternativeName(); sanAlternateName.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_RFC822_NAME, sanSubjectName); CAlternativeNames sanAlternativeNames = new CAlternativeNames(); sanAlternativeNames.Add(sanAlternateName); CX509ExtensionAlternativeNames alternativeNamesExtension = new CX509ExtensionAlternativeNames(); alternativeNamesExtension.InitializeEncode(sanAlternativeNames); CX509ExtensionSmimeCapabilities smimeCapabilities = new CX509ExtensionSmimeCapabilities(); smimeCapabilities.SmimeCapabilities.AddAvailableSmimeCapabilities(false); // Create the self-signing request. CX509CertificateRequestCertificate cert = new CX509CertificateRequestCertificate(); cert.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextMachine, privateKey, ""); cert.Subject = distinguishedName; cert.Issuer = distinguishedName; cert.NotBefore = DateTime.Now; cert.NotAfter = DateTime.Now.AddYears(1); cert.X509Extensions.Add((CX509Extension)keyUsage); cert.X509Extensions.Add((CX509Extension)enhancedKeyUsages); cert.X509Extensions.Add((CX509Extension)alternativeNamesExtension); cert.X509Extensions.Add((CX509Extension)smimeCapabilities); cert.HashAlgorithm = hashAlgorithm; cert.Encode(); return cert; }
public X509Certificate2 CreateSelfSignedCertificate(string FriendlyName, string SubjectName) { try { // Create DN for Subject CX500DistinguishedName dnSubject = new CX500DistinguishedName(); dnSubject.Encode(String.Format(@"CN={0}", SubjectName), X500NameFlags.XCN_CERT_NAME_STR_NONE); // Create DN for Issuer CX500DistinguishedName dnIssuer = new CX500DistinguishedName(); dnIssuer.Encode(String.Format(@"CN={0}", IssuerName), X500NameFlags.XCN_CERT_NAME_STR_NONE); // Use the stronger SHA512 hashing algorithm CObjectId HashAlgorithm = new CObjectId(); HashAlgorithm.InitializeFromAlgorithmName(ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID, ObjectIdPublicKeyFlags.XCN_CRYPT_OID_INFO_PUBKEY_ANY, AlgorithmFlags.AlgorithmFlagsNone, strAlgorithmName); // add extended key usage if you want - look at MSDN for a list of possible OIDs CObjectId oid1 = new CObjectId(); oid1.InitializeFromValue("1.3.6.1.5.5.7.3.1"); // SSL Server CObjectId oid2 = new CObjectId(); oid2.InitializeFromValue("1.3.6.1.5.5.7.3.2"); // SSL Client CObjectIds oidlist = new CObjectIds(); oidlist.Add(oid1); oidlist.Add(oid2); CX509ExtensionEnhancedKeyUsage eku = new CX509ExtensionEnhancedKeyUsage(); eku.InitializeEncode(oidlist); CX509ExtensionAlternativeNames objExtensionAlternativeNames = new CX509ExtensionAlternativeNames(); { CAlternativeNames altNames = new CAlternativeNames(); CAlternativeName dnsLocalHost = new CAlternativeName(); dnsLocalHost.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME, "LOCALHOST"); altNames.Add(dnsLocalHost); CAlternativeName dnsHostname = new CAlternativeName(); dnsHostname.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME, Environment.MachineName); altNames.Add(dnsHostname); foreach (var ipAddress in Dns.GetHostAddresses(Dns.GetHostName())) { if ((ipAddress.AddressFamily == AddressFamily.InterNetwork) && !IPAddress.IsLoopback(ipAddress)) { CAlternativeName dns = new CAlternativeName(); dns.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME, ipAddress.ToString()); altNames.Add(dns); } } objExtensionAlternativeNames.InitializeEncode(altNames); } //CX509ExtensionSmimeCapabilities smimeCapabilities = new CX509ExtensionSmimeCapabilities(); //smimeCapabilities.SmimeCapabilities.AddAvailableSmimeCapabilities(false); CX509ExtensionBasicConstraints basicConst = new CX509ExtensionBasicConstraints(); basicConst.InitializeEncode(dnSubject.Name == dnIssuer.Name ? true : false, 1); // Key Usage Extension CX509ExtensionKeyUsage objExtensionKeyUsage = new CX509ExtensionKeyUsage(); objExtensionKeyUsage.InitializeEncode( CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_DIGITAL_SIGNATURE_KEY_USAGE | CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_NON_REPUDIATION_KEY_USAGE | CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_KEY_ENCIPHERMENT_KEY_USAGE | CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_DATA_ENCIPHERMENT_KEY_USAGE | CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_KEY_CERT_SIGN_KEY_USAGE ); // Create the self signing request CX509CertificateRequestCertificate cert = new CX509CertificateRequestCertificate(); cert.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextMachine, PrivateKey, ""); cert.Subject = dnSubject; cert.Issuer = dnIssuer; cert.NotBefore = DateTime.Today.AddDays(-1); cert.NotAfter = DateTime.Today.AddYears(ExpirationLengthInYear); cert.X509Extensions.Add((CX509Extension)eku); // add the EKU cert.X509Extensions.Add((CX509Extension)objExtensionAlternativeNames); cert.X509Extensions.Add((CX509Extension)objExtensionKeyUsage); cert.X509Extensions.Add((CX509Extension)basicConst); //cert.X509Extensions.Add((CX509Extension)smimeCapabilities); cert.HashAlgorithm = HashAlgorithm; // Specify the hashing algorithm cert.Encode(); // encode the certificate // Do the final enrollment process CX509Enrollment enroll = new CX509Enrollment(); enroll.InitializeFromRequest(cert); // load the certificate enroll.CertificateFriendlyName = FriendlyName; // Optional: add a friendly name string csr = enroll.CreateRequest(); // Output the request in base64 and install it back as the response // no password output a base64 encoded PKCS#12 so we can import it back to the .Net security classes enroll.InstallResponse(InstallResponseRestrictionFlags.AllowUntrustedCertificate, csr, EncodingType.XCN_CRYPT_STRING_BASE64, ""); // no password, this is for internal consumption var base64encoded = enroll.CreatePFX("", PFXExportOptions.PFXExportChainWithRoot); // instantiate the target class with the PKCS#12 data (and the empty password) // mark the private key as exportable (this is usually what you want to do) return(new X509Certificate2(Convert.FromBase64String(base64encoded), "", X509KeyStorageFlags.Exportable)); } catch (Exception ex) { throw new Exception(ex.Message); } }
public string CreateRequest() { // Create all the objects that will be required var objPkcs10 = new CX509CertificateRequestPkcs10(); var objPrivKey = new CX509PrivateKey(); var objCSP = new CCspInformation(); var objCSPs = new CCspInformations(); var objDN = new CX500DistinguishedName(); var objEnroll = new CX509Enrollment(); var objObjIds = new CObjectIds(); var objObjId = new CObjectId(); var objExtKeyUsage = new CX509ExtensionKeyUsage(); var objExtEnhKeyUsage = new CX509ExtensionEnhancedKeyUsage(); string strRequest; //objCSP.InitializeFromName(provName); //objCSPs.Add(objCSP); //objPrivKey.Length = 2048; //objPrivKey.KeySpec = X509KeySpec.XCN_AT_KEYEXCHANGE; //objPrivKey.KeyUsage = X509PrivateKeyUsageFlags.XCN_NCRYPT_ALLOW_ALL_USAGES; //objPrivKey.MachineContext = true; //objPrivKey.CspInformations = objCSPs; //objPrivKey.Create(); var strTemplateName = "1.3.6.1.4.1.311.21.8.12017375.10856495.934812.8687423.15807460.10.5731641.6795722"; // RDP All Names objPkcs10.InitializeFromTemplateName(X509CertificateEnrollmentContext.ContextMachine, strTemplateName); // Encode the name in using the DN object objDN.Encode("CN=" + Environment.GetEnvironmentVariable("COMPUTERNAME"), X500NameFlags.XCN_CERT_NAME_STR_NONE); // Adding the subject name by using the DN object initialized above objPkcs10.Subject = objDN; var dnsDom = Environment.GetEnvironmentVariable("USERDNSDOMAIN").ToLower(); var altName = new CAlternativeName(); var objAlternateNames = new CAlternativeNames(); var objExtAltNames = new CX509ExtensionAlternativeNames(); altName.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME, Environment.GetEnvironmentVariable("COMPUTERNAME") + "." + dnsDom); var altName2 = new CAlternativeName(); altName2.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME, Environment.GetEnvironmentVariable("COMPUTERNAME")); objAlternateNames.Add(altName2); objAlternateNames.Add(altName); objExtAltNames.InitializeEncode(objAlternateNames); objPkcs10.X509Extensions.Add((CX509Extension)objExtAltNames); // Create the enrollment request objEnroll.InitializeFromRequest(objPkcs10); strRequest = objEnroll.CreateRequest(EncodingType.XCN_CRYPT_STRING_BASE64); return(strRequest); }