/// <summary> /// Generate a self-signed certificate and add it to the Windows certificate store. /// </summary> /// <param name="subjectName">The subject name of the certificate.</param> /// <param name="friendlyName">The friendly name of the certificate.</param> /// <param name="location">Location of the certificate; either the Current User or Local Machine.</param> /// <param name="addAsTrustedRoot">Whether to add the generated certificate as a trusted root.</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 X509Certificate2 CreateSelfSignedCertificate(string subjectName, string friendlyName, StoreLocation location, bool addAsTrustedRoot, int keyLength, int durationYears, List <string> oids) { // Create the self-signing request. CX509CertificateRequestCertificate cert = CreateCertificateSigningRequest(subjectName, keyLength, durationYears, oids); // Enroll based on the certificate signing request. CX509Enrollment enrollment = new CX509Enrollment(); enrollment.InitializeFromRequest(cert); enrollment.CertificateFriendlyName = friendlyName; string csrText = enrollment.CreateRequest(EncodingType.XCN_CRYPT_STRING_BASE64); // Install the certificate chain. Note that no password is specified. enrollment.InstallResponse(InstallResponseRestrictionFlags.AllowUntrustedCertificate, csrText, EncodingType.XCN_CRYPT_STRING_BASE64, ""); // Base-64 encode the PKCS#12 certificate in order to re-import it. string pfx = enrollment.CreatePFX("", PFXExportOptions.PFXExportChainWithRoot); // Instantiate the PKCS#12 certificate. X509Certificate2 certificate = new X509Certificate2(System.Convert.FromBase64String(pfx), "", X509KeyStorageFlags.Exportable); // If specified, also install the certificate to the trusted root store. if (addAsTrustedRoot) { X509Store rootStore = new X509Store(StoreName.Root, location); rootStore.Open(OpenFlags.ReadWrite); rootStore.Add(certificate); rootStore.Close(); } return(certificate); }
/// <summary> /// Installs the certificate /// </summary> /// <returns></returns> public X509Certificate2 InstallCertficate() { CX509Enrollment objEnroll = new CX509Enrollment(); try { // Install the certificate objEnroll.InitializeFromRequest(objCertRequest); objEnroll.InstallResponse( this.InstallResponseRestrictionFlags, stringResponse, this.EncodingType, this.Password ); var base64encoded = objEnroll.CreatePFX(this.Password, PFXExportOptions.PFXExportChainWithRoot); return(new System.Security.Cryptography.X509Certificates.X509Certificate2( System.Convert.FromBase64String(base64encoded), this.Password, this.ExportableFlags)); } catch (Exception ex) { throw ex; } }
/// <summary> /// Creates a self signed certificate given the parameters. /// </summary> /// <param name="subject"></param> /// <param name="cipher"></param> /// <param name="keysize"></param> /// <param name="api"></param> /// <returns></returns> public X509Certificate2 CreateSelfSignedCertificate(CertificateSubject subject, CipherAlgorithm cipher, int keysize, WindowsApi api) { CX509PrivateKey privateKey = CreatePrivateKey(cipher, keysize); CX509CertificateRequestCertificate pkcs10 = NewCertificateRequestCrc(subject, privateKey); pkcs10.Issuer = pkcs10.Subject; pkcs10.NotBefore = DateTime.Now.AddDays(-1); pkcs10.NotAfter = DateTime.Now.AddYears(20); var sigoid = new CObjectId(); var alg = new Oid("SHA256"); sigoid.InitializeFromValue(alg.Value); pkcs10.SignatureInformation.HashAlgorithm = sigoid; pkcs10.Encode(); CX509Enrollment enrollment = new CX509Enrollment(); enrollment.InitializeFromRequest(pkcs10); string csr = enrollment.CreateRequest(EncodingType.XCN_CRYPT_STRING_BASE64); InstallResponseRestrictionFlags restrictionFlags = InstallResponseRestrictionFlags.AllowUntrustedCertificate; enrollment.InstallResponse(restrictionFlags, csr, EncodingType.XCN_CRYPT_STRING_BASE64, string.Empty); string pwd = secret.NewSecret(16); string pfx = enrollment.CreatePFX(pwd, PFXExportOptions.PFXExportChainWithRoot, EncodingType.XCN_CRYPT_STRING_BASE64); return(new X509Certificate2(Convert.FromBase64String(pfx), pwd)); }
// create a certificate for testing // https://stackoverflow.com/q/18339706 static public X509Certificate2 CreateSelfSignedCertificate(string subjectName, TimeSpan expirationLength) { // create DN for subject and issuer var dn = new CX500DistinguishedName(); dn.Encode("CN=" + subjectName, X500NameFlags.XCN_CERT_NAME_STR_NONE); CX509PrivateKey privateKey = new CX509PrivateKey { ProviderName = "Microsoft Strong Cryptographic Provider", Length = 2048, KeySpec = X509KeySpec.XCN_AT_KEYEXCHANGE, KeyUsage = X509PrivateKeyUsageFlags.XCN_NCRYPT_ALLOW_DECRYPT_FLAG | X509PrivateKeyUsageFlags.XCN_NCRYPT_ALLOW_KEY_AGREEMENT_FLAG, MachineContext = true, 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; // 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 = 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) return(new System.Security.Cryptography.X509Certificates.X509Certificate2( System.Convert.FromBase64String(base64encoded), "", // mark the private key as exportable (this is usually what you want to do) // mark private key to go into the Machine store instead of the current users store X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet )); }
private string CreateCertificate(string publisherName) { var cert = CreateCertificateRequest(publisherName); AddKeyUsage(cert); AddExtendedKeyUsage(cert); AddBasicConstraints(cert); // Specify the 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, "SHA256"); cert.HashAlgorithm = hashobj; cert.Encode(); // Do the final enrollment process var enrollment = new CX509Enrollment(); enrollment.InitializeFromRequest(cert); // load the certificate enrollment.CertificateFriendlyName = cert.Subject.Name; var request = enrollment.CreateRequest(); enrollment.InstallResponse(InstallResponseRestrictionFlags.AllowUntrustedCertificate, request, EncodingType.XCN_CRYPT_STRING_BASE64, ""); var base64Encoded = enrollment.CreatePFX("", PFXExportOptions.PFXExportChainWithRoot); return(base64Encoded); }
/// <summary> /// Load the response from the CA -- just the signed certificate, not the signers. /// </summary> /// <param name="pem_response">Signed certificate</param> /// <returns>The full certificate</returns> public static X509Certificate2 LoadResponse(string pem_response, StoreLocation loc) { X509Certificate2 cert; CX509Enrollment objEnroll = new CX509Enrollment(); if (loc == StoreLocation.LocalMachine) { objEnroll.Initialize(X509CertificateEnrollmentContext.ContextMachine); } else { objEnroll.Initialize(X509CertificateEnrollmentContext.ContextUser); } objEnroll.InstallResponse( InstallResponseRestrictionFlags.AllowUntrustedRoot, pem_response, EncodingType.XCN_CRYPT_STRING_BASE64HEADER, null ); string pfx_string = objEnroll.CreatePFX("dummypw", PFXExportOptions.PFXExportEEOnly, EncodingType.XCN_CRYPT_STRING_BASE64); byte[] pfx_binary_data = System.Convert.FromBase64String(pfx_string); cert = new X509Certificate2(pfx_binary_data, "dummypw", X509KeyStorageFlags.Exportable); //CreatedCert = cert; return(cert); }
public static X509Certificate2 CreateSelfSignedCertificate(string issuer, string name) { try { // create a DN for issuer and subject var dn = new CX500DistinguishedName(); dn.Encode("CN=" + issuer, X500NameFlags.XCN_CERT_NAME_STR_NONE); // create a private key for the certificate var privateKey = new CX509PrivateKey(); privateKey.ProviderName = "Microsoft Base Cryptographic Provider v1.0"; privateKey.MachineContext = true; privateKey.Length = 2048; privateKey.KeySpec = X509KeySpec.XCN_AT_SIGNATURE; 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"); // add extended key usage (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 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, ""); cert.Issuer = dn; cert.Subject = dn; cert.NotBefore = DateTime.Now; cert.NotAfter = DateTime.Now.AddYears(1); // 1 year expiration cert.X509Extensions.Add((CX509Extension)eku); cert.HashAlgorithm = hashobj; cert.Encode(); // do the final enrollment process var enroll = new CX509Enrollment(); enroll.InitializeFromRequest(cert); enroll.CertificateFriendlyName = name; string csr = enroll.CreateRequest(); // output a base64 encoded PKCS#12 enroll.InstallResponse(InstallResponseRestrictionFlags.AllowUntrustedCertificate, csr, EncodingType.XCN_CRYPT_STRING_BASE64, ""); var base64encoded = enroll.CreatePFX("", PFXExportOptions.PFXExportChainWithRoot); // return the certificate return(new X509Certificate2(Convert.FromBase64String(base64encoded), "", X509KeyStorageFlags.Exportable)); } catch (Exception exc) { Trace.TraceError("Failed to create a self-signed certificate ({0})", exc); throw; } }
public static X509Certificate2 CreateSelfSignedCertificate(string subjectName) { //To make a certificate was used system library from CERTENROLLLib //This lib provides methods for creation certificates in windows envinronment //Defines the subject and issuer of the cert CX500DistinguishedName dn = new CX500DistinguishedName(); dn.Encode("CN=" + subjectName, X500NameFlags.XCN_CERT_NAME_STR_NONE); //Create a new private key for the certificate //Was decided not to make them variably in this progr CX509PrivateKey privateKey = new CX509PrivateKey(); privateKey.ProviderName = "Microsoft Base Cryptographic Provider v1.0"; //issuer for a selfsigned certificate 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.Create(); //Use trong 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; cert.NotAfter = new DateTime(2018, 12, 31); // I don't think that anybody cares about using this cert longer than this period cert.HashAlgorithm = hashobj; // Specify the hashing algorithm cert.Encode(); // Encode the certificate // Do the final stuff //Enroll is var enroll = new CX509Enrollment(); enroll.InitializeFromRequest(cert); // load the certificate 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("", // password isn't possible PFXExportOptions.PFXExportChainWithRoot); // instantiate the target class with the PKCS#12 data (and the empty password) return(new X509Certificate2(Convert.FromBase64String(base64encoded), "", // mark the private key as exportable, coz we want to put it into registry X509KeyStorageFlags.Exportable)); }
public static X509Certificate2 CreateSelfSignedCertificate(string subjectName, DateTime startDate, DateTime endDate, String password) { // Create DistinguishedName for subject and issuer var name = new CX500DistinguishedName(); name.Encode("CN=" + subjectName, X500NameFlags.XCN_CERT_NAME_STR_NONE); // Create a new Private Key for the certificate CX509PrivateKey privateKey = new CX509PrivateKey(); privateKey.ProviderName = "Microsoft RSA SChannel Cryptographic Provider"; privateKey.KeySpec = X509KeySpec.XCN_AT_KEYEXCHANGE; privateKey.Length = 2048; privateKey.SecurityDescriptor = "D:PAI(A;;0xd01f01ff;;;SY)(A;;0xd01f01ff;;;BA)(A;;0x80120089;;;NS)"; privateKey.MachineContext = true; privateKey.ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_FLAG; privateKey.Create(); // Define the hashing algorithm var serverauthoid = new CObjectId(); serverauthoid.InitializeFromValue("1.3.6.1.5.5.7.3.1"); // Server Authentication var ekuoids = new CObjectIds(); ekuoids.Add(serverauthoid); var ekuext = new CX509ExtensionEnhancedKeyUsage(); ekuext.InitializeEncode(ekuoids); // Create the self signing request var cert = new CX509CertificateRequestCertificate(); cert.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextMachine, privateKey, String.Empty); cert.Subject = name; cert.Issuer = cert.Subject; cert.NotBefore = startDate; cert.NotAfter = endDate; cert.X509Extensions.Add((CX509Extension)ekuext); cert.Encode(); // Enroll the certificate var enroll = new CX509Enrollment(); enroll.InitializeFromRequest(cert); string certData = enroll.CreateRequest(EncodingType.XCN_CRYPT_STRING_BASE64HEADER); enroll.InstallResponse(InstallResponseRestrictionFlags.AllowUntrustedCertificate, certData, EncodingType.XCN_CRYPT_STRING_BASE64HEADER, String.Empty); var base64encoded = enroll.CreatePFX(password, PFXExportOptions.PFXExportChainWithRoot); // Instantiate the target class with the PKCS#12 data return(new X509Certificate2( System.Convert.FromBase64String(base64encoded), password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.Exportable)); }
protected static void ExportCertificate(byte[] certificateData, string outputPath, string password) { var certificateEnrollmentContext = X509CertificateEnrollmentContext.ContextUser; CX509Enrollment cx509Enrollment = new CX509Enrollment(); cx509Enrollment.Initialize(certificateEnrollmentContext); cx509Enrollment.InstallResponse(InstallResponseRestrictionFlags.AllowUntrustedCertificate, Convert.ToBase64String(certificateData), EncodingType.XCN_CRYPT_STRING_BASE64, null); var pfx = cx509Enrollment.CreatePFX(password, PFXExportOptions.PFXExportChainNoRoot, EncodingType.XCN_CRYPT_STRING_BASE64); using (var fs = File.OpenWrite(outputPath)) { var decoded = Convert.FromBase64String(pfx); fs.Write(decoded, 0, decoded.Length); } }
public void InstallAndDownload(string certText, string password, string friendlyName) { var enroll = new CX509Enrollment(); enroll.Initialize(X509CertificateEnrollmentContext.ContextUser); enroll.CertificateFriendlyName = friendlyName; enroll.InstallResponse(InstallResponseRestrictionFlags.AllowUntrustedRoot, certText, EncodingType.XCN_CRYPT_STRING_BASE64REQUESTHEADER, password ); var dir = Directory.GetParent(Assembly.GetExecutingAssembly().Location).ToString(); var pfx = enroll.CreatePFX(password, PFXExportOptions.PFXExportChainWithRoot); var fileName = "cert.pfx"; var filePath = $@"{dir}\{fileName}"; Download(filePath, pfx); Install(filePath, password); }
// https://github.com/asafga-gsr-it/CertIntegration/blob/master/CertificateAdmin/CertificateAdmin/obj/Release/Package/PackageTmp/Certificate.cs // https://www.sysadmins.lv/blog-en/introducing-to-certificate-enrollment-apis-part-2-creating-offline-requests.aspx /* * public static X509Certificate2 CreateSelfSignedCA(string subjectName, DateTime notAfterUtc, bool machineContext) * { * // create DN for subject and issuer * var dn = new CX500DistinguishedName(); * dn.Encode("CN=" + EscapeDNComponent(subjectName), X500NameFlags.XCN_CERT_NAME_STR_NONE); * * // create a new private key for the certificate * CX509PrivateKey privateKey = new CX509PrivateKey(); * privateKey.ProviderName = "Microsoft Base Cryptographic Provider v1.0"; * privateKey.MachineContext = machineContext; * privateKey.Length = 2048; * privateKey.KeySpec = X509KeySpec.XCN_AT_SIGNATURE; // use is not limited * privateKey.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, "SHA256"); // https://docs.microsoft.com/en-us/windows/win32/seccng/cng-algorithm-identifiers * * CX509ExtensionKeyUsage keyUsage = new CX509ExtensionKeyUsage(); * keyUsage.InitializeEncode( * 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); * * CX509ExtensionBasicConstraints bc = new CX509ExtensionBasicConstraints(); * bc.InitializeEncode(true, -1); // None * bc.Critical = true; * * // 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"); // Server Authentication * 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(machineContext ? X509CertificateEnrollmentContext.ContextMachine: X509CertificateEnrollmentContext.ContextUser, privateKey, ""); * cert.Subject = cert.Issuer = dn; // the issuer and the subject are the same * cert.NotBefore = DateTime.UtcNow.AddDays(-1); * cert.NotAfter = notAfterUtc; * cert.X509Extensions.Add((CX509Extension)keyUsage); * cert.X509Extensions.Add((CX509Extension)eku); // add the EKU * cert.X509Extensions.Add((CX509Extension)bc); * 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 = subjectName; // Optional: add a friendly name * string csr = enroll.CreateRequest(); // Output the request in base64 * * // install to MY store * 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( * System.Convert.FromBase64String(base64encoded), "", * // mark the private key as exportable (this is usually what you want to do) * X509KeyStorageFlags.Exportable * ); * * X509Store rootStore = null; * try * { * rootStore = new X509Store(StoreName.Root, 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(); * } * * return x509Certificate2; * } */ public static X509Certificate2 CreateCertificate(string subjectName, string hostname, DateTime notAfterUtc, X509Certificate issuer, bool machineContext) { CSignerCertificate signerCertificate = new CSignerCertificate(); signerCertificate.Initialize(false, X509PrivateKeyVerify.VerifyNone, EncodingType.XCN_CRYPT_STRING_HEX, issuer.GetRawCertDataString()); // create DN for subject and issuer var dn = new CX500DistinguishedName(); dn.Encode("CN=" + EscapeDNComponent(subjectName), X500NameFlags.XCN_CERT_NAME_STR_NONE); // create a new private key for the certificate CX509PrivateKey privateKey = new CX509PrivateKey(); privateKey.ProviderName = "Microsoft Base Cryptographic Provider v1.0"; privateKey.MachineContext = machineContext; privateKey.Length = 2048; privateKey.KeySpec = X509KeySpec.XCN_AT_SIGNATURE; // use is not limited privateKey.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, "SHA256"); CX509ExtensionKeyUsage keyUsage = new CX509ExtensionKeyUsage(); keyUsage.InitializeEncode( CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_DATA_ENCIPHERMENT_KEY_USAGE | CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_KEY_ENCIPHERMENT_KEY_USAGE | CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_DIGITAL_SIGNATURE_KEY_USAGE); CX509ExtensionBasicConstraints bc = new CX509ExtensionBasicConstraints(); bc.InitializeEncode(false, 0); bc.Critical = false; // SAN CX509ExtensionAlternativeNames san = null; if (!string.IsNullOrEmpty(hostname)) { CAlternativeNames ians; if (IPAddress.TryParse(hostname, out var ip)) { var ian = new CAlternativeName(); ian.InitializeFromRawData(AlternativeNameType.XCN_CERT_ALT_NAME_IP_ADDRESS, EncodingType.XCN_CRYPT_STRING_BASE64, Convert.ToBase64String(ip.GetAddressBytes())); ians = new CAlternativeNames { ian }; } else { var ian = new CAlternativeName(); ian.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME, hostname); var ianStar = new CAlternativeName(); ianStar.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME, "*." + hostname); // wildcard ians = new CAlternativeNames { ian, ianStar }; } san = new CX509ExtensionAlternativeNames(); san.InitializeEncode(ians); } // 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 var oidlist = new CObjectIds(); oidlist.Add(oid); var eku = new CX509ExtensionEnhancedKeyUsage(); eku.InitializeEncode(oidlist); var dnIssuer = new CX500DistinguishedName(); dnIssuer.Encode(issuer.Subject, X500NameFlags.XCN_CERT_NAME_STR_NONE); // Create the self signing request var cert = new CX509CertificateRequestCertificate(); cert.InitializeFromPrivateKey(machineContext ? X509CertificateEnrollmentContext.ContextMachine : X509CertificateEnrollmentContext.ContextUser, privateKey, ""); cert.Subject = dn; cert.Issuer = dnIssuer; cert.SignerCertificate = signerCertificate; cert.NotBefore = DateTime.UtcNow.AddDays(-1); cert.NotAfter = notAfterUtc; cert.X509Extensions.Add((CX509Extension)keyUsage); cert.X509Extensions.Add((CX509Extension)eku); // EnhancedKeyUsage cert.X509Extensions.Add((CX509Extension)bc); // ExtensionBasicConstraints if (san != null) { cert.X509Extensions.Add((CX509Extension)san); // SAN } 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 = 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) return(x509Certificate2); }
/// <summary> /// Add Reference: COM > TypeLibraries > CertEnroll 1.0 Type Library /// </summary> /// <param name="subjectName"></param> /// <returns></returns> public static X509Certificate2 CreateSelfSignedCertificate(string subjectName, TimeSpan expiresIn) { // create DN for subject and issuer var dn = new CX500DistinguishedName(); dn.Encode("CN=" + subjectName, X500NameFlags.XCN_CERT_NAME_STR_NONE); // create a new private key for the certificate CX509PrivateKey privateKey = new CX509PrivateKey(); 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.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 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, ""); cert.Subject = dn; cert.Issuer = dn; // the issuer and the subject are the same cert.NotBefore = DateTime.Now; // this cert expires immediately. Change to whatever makes sense for you cert.NotAfter = DateTime.Now.Add(expiresIn); 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 = 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) return(new System.Security.Cryptography.X509Certificates.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 )); }
/// <summary> /// Creates a self-signed cert. /// </summary> /// <param name="subject"></param> /// <param name="notAfter"></param> /// <param name="pwd"></param> /// <returns></returns> /// <remarks> /// https://blogs.msdn.microsoft.com/alejacma/2008/09/05/how-to-create-a-certificate-request-with-certenroll-and-net-c/ /// http://stackoverflow.com/questions/13806299/how-to-create-a-self-signed-certificate-using-c /// https://technet.microsoft.com/es-es/aa379410 /// </remarks> public static X509Certificate2 CreateSelfSignedCert(DistinguishedName subject, DateTime notAfter, String pwd) { var cn = new CX500DistinguishedName(); cn.Encode(subject.ToString(), X500NameFlags.XCN_CERT_NAME_STR_SEMICOLON_FLAG); var privateKey = new CX509PrivateKey { ContainerNamePrefix = "nf-", ProviderName = MS_CRYPTO_PROV_NAME, MachineContext = false, Length = 2048, KeySpec = X509KeySpec.XCN_AT_KEYEXCHANGE, ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_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, RSAPKCS1SHA512SigDesc.SHA_512); var keyUsage = new CX509ExtensionKeyUsage(); keyUsage.InitializeEncode(X509KeyUsageFlags.XCN_CERT_DIGITAL_SIGNATURE_KEY_USAGE | X509KeyUsageFlags.XCN_CERT_DATA_ENCIPHERMENT_KEY_USAGE); //add extended key usage var serverAuth = new CObjectId(); serverAuth.InitializeFromValue("1.3.6.1.5.5.7.3.1"); var clientAuth = new CObjectId(); clientAuth.InitializeFromValue("1.3.6.1.5.5.7.3.2"); var fileCrypt = new CObjectId(); fileCrypt.InitializeFromValue("1.3.6.1.4.1.311.10.3.4"); var docSign = new CObjectId(); docSign.InitializeFromValue("1.3.6.1.4.1.311.10.3.12"); var oidList = new CObjectIds { serverAuth, fileCrypt, docSign }; var eku = new CX509ExtensionEnhancedKeyUsage(); eku.InitializeEncode(oidList); var cert = new CX509CertificateRequestCertificate(); cert.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextUser, privateKey, ""); cert.Subject = cn; cert.Issuer = cn; cert.NotBefore = DateTime.Now; cert.NotAfter = notAfter; cert.X509Extensions.Add((CX509Extension)keyUsage); cert.X509Extensions.Add((CX509Extension)eku); cert.HashAlgorithm = hashobj; cert.Encode(); var enroll = new CX509Enrollment(); enroll.InitializeFromRequest(cert); enroll.CertificateFriendlyName = subject.CommonName; var csr = enroll.CreateRequest(); enroll.InstallResponse(InstallResponseRestrictionFlags.AllowUntrustedRoot, csr, EncodingType.XCN_CRYPT_STRING_BASE64, pwd); var b64Encode = enroll.CreatePFX(pwd, PFXExportOptions.PFXExportEEOnly); var managedX509Cert = new X509Certificate2(Convert.FromBase64String(b64Encode), pwd, X509KeyStorageFlags.Exportable); return(managedX509Cert); }
public static X509Certificate2 CreateCertificate(string subjectName, int days, X509Certificate2 issuer) { CSignerCertificate signerCertificate = new CSignerCertificate(); signerCertificate.Initialize(true, X509PrivateKeyVerify.VerifyNone, EncodingType.XCN_CRYPT_STRING_HEX, issuer.GetRawCertDataString()); // create DN for subject and issuer var dn = new CX500DistinguishedName(); dn.Encode("CN=" + subjectName, X500NameFlags.XCN_CERT_NAME_STR_NONE); // create a new private key for the certificate CX509PrivateKey privateKey = new CX509PrivateKey(); 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.Create(); var hashobj = new CObjectId(); hashobj.InitializeFromAlgorithmName(ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID, ObjectIdPublicKeyFlags.XCN_CRYPT_OID_INFO_PUBKEY_ANY, AlgorithmFlags.AlgorithmFlagsNone, "SHA256"); CX509ExtensionKeyUsage keyUsage = new CX509ExtensionKeyUsage(); keyUsage.InitializeEncode(CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_DATA_ENCIPHERMENT_KEY_USAGE | CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_KEY_ENCIPHERMENT_KEY_USAGE | CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_DIGITAL_SIGNATURE_KEY_USAGE); CX509ExtensionBasicConstraints bc = new CX509ExtensionBasicConstraints(); bc.InitializeEncode(false, 0); bc.Critical = false; // 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 var oidlist = new CObjectIds(); oidlist.Add(oid); var eku = new CX509ExtensionEnhancedKeyUsage(); eku.InitializeEncode(oidlist); var dnIssuer = new CX500DistinguishedName(); dnIssuer.Encode(issuer.Subject, X500NameFlags.XCN_CERT_NAME_STR_NONE); // Create the self signing request var cert = new CX509CertificateRequestCertificate(); cert.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextMachine, privateKey, ""); cert.Subject = dn; cert.Issuer = dnIssuer; cert.SignerCertificate = signerCertificate; cert.NotBefore = DateTime.UtcNow.Date.AddDays(-1); cert.NotAfter = DateTime.UtcNow.Date.AddDays(days); cert.X509Extensions.Add((CX509Extension)keyUsage); cert.X509Extensions.Add((CX509Extension)eku); // add the EKU cert.X509Extensions.Add((CX509Extension)bc); /* * var ski = new CX509ExtensionAuthorityKeyIdentifier(); * ski.InitializeEncode(EncodingType.XCN_CRYPT_STRING_BINARY, cert.PublicKey.ComputeKeyIdentifier(KeyIdentifierHashAlgorithm.SKIHashSha1, EncodingType.XCN_CRYPT_STRING_BINARY)); * cert.X509Extensions.Add((CX509Extension)ski); */ 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 = 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 System.Security.Cryptography.X509Certificates.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); return(x509Certificate2); }
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 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); } }
private static string CreateCertContent(string cn, TimeSpan expirationLength, string pwd) { var base64encoded = string.Empty; var dn = new CX500DistinguishedName(); dn.Encode("CN=" + cn, X500NameFlags.XCN_CERT_NAME_STR_NONE); var 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, "SHA256"); // 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; // 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 var 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; }
/* * http://stackoverflow.com/questions/13806299/how-to-create-a-self-signed-certificate-using-c * This implementation uses the CX509CertificateRequestCertificate COM object (and friends - MSDN doc) from certenroll.dll to create a self signed certificate request and sign it. */ public static X509Certificate2 CreateSelfSignedCertificateCOM(string subjectName) { // create DN for subject and issuer var dn = new CX500DistinguishedName(); dn.Encode("CN=" + subjectName, X500NameFlags.XCN_CERT_NAME_STR_NONE); // create a new private key for the certificate CX509PrivateKey privateKey = new CX509PrivateKey(); privateKey.ProviderName = "Microsoft Enhanced RSA and AES Cryptographic Provider"; 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.KeyUsage = X509PrivateKeyUsageFlags.XCN_NCRYPT_ALLOW_SIGNING_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, "SHA256"); // 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 //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, ""); cert.Subject = dn; cert.Issuer = dn; // the issuer and the subject are the same cert.NotBefore = DateTime.Now.Subtract(new TimeSpan(1, 0, 0, 0)); cert.NotAfter = DateTime.Now.Add(new TimeSpan(30,0,0,0)); //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 = 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) return new System.Security.Cryptography.X509Certificates.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 ); }
/// <summary> /// Generate a self-signed certificate and add it to the Windows certificate store. /// </summary> /// <param name="subjectName">The subject name of the certificate.</param> /// <param name="friendlyName">The friendly name of the certificate.</param> /// <param name="location">Location of the certificate; either the Current User or Local Machine.</param> /// <param name="addAsTrustedRoot">Whether to add the generated certificate as a trusted root.</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 X509Certificate2 CreateSelfSignedCertificate(string subjectName, string friendlyName, StoreLocation location, bool addAsTrustedRoot, int keyLength, int durationYears, List<string> oids) { // Create the self-signing request. CX509CertificateRequestCertificate cert = CreateCertificateSigningRequest(subjectName, keyLength, durationYears, oids); // Enroll based on the certificate signing request. CX509Enrollment enrollment = new CX509Enrollment(); enrollment.InitializeFromRequest(cert); enrollment.CertificateFriendlyName = friendlyName; string csrText = enrollment.CreateRequest(EncodingType.XCN_CRYPT_STRING_BASE64); // Install the certificate chain. Note that no password is specified. enrollment.InstallResponse(InstallResponseRestrictionFlags.AllowUntrustedCertificate, csrText, EncodingType.XCN_CRYPT_STRING_BASE64, ""); // Base-64 encode the PKCS#12 certificate in order to re-import it. string pfx = enrollment.CreatePFX("", PFXExportOptions.PFXExportChainWithRoot); // Instantiate the PKCS#12 certificate. X509Certificate2 certificate = new X509Certificate2(System.Convert.FromBase64String(pfx), "", X509KeyStorageFlags.Exportable); // If specified, also install the certificate to the trusted root store. if (addAsTrustedRoot) { X509Store rootStore = new X509Store(StoreName.Root, location); rootStore.Open(OpenFlags.ReadWrite); rootStore.Add(certificate); rootStore.Close(); } return certificate; }
public static X509Certificate2 CreateSelfSignedCertificateOldImplementationNetFramework( string subjectName, string friendlyName, ILoggerInterface logger, int expirationDays = 90) { // create DN for subject var dn = new CX500DistinguishedName(); dn.Encode("CN=" + subjectName, X500NameFlags.XCN_CERT_NAME_STR_NONE); // create DN for the issuer var issuer = new CX500DistinguishedName(); issuer.Encode("CN=ChefCertificate", X500NameFlags.XCN_CERT_NAME_STR_NONE); // create a new private key for the certificate CX509PrivateKey privateKey = new CX509PrivateKey(); 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.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 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, string.Empty); cert.Subject = dn; cert.Issuer = issuer; cert.NotBefore = DateTime.Now; // this cert expires immediately. Change to whatever makes sense for you cert.NotAfter = DateTime.Now.AddDays(expirationDays); 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, string.Empty); // no password // output a base64 encoded PKCS#12 so we can import it back to the .Net security classes var base64Encoded = enroll.CreatePFX( string.Empty, // no password, this is for internal consumption PFXExportOptions.PFXExportChainWithRoot); // Delete the key var storePath = UtilsCertificate.FindKeyStoragePath(privateKey.UniqueContainerName); if (string.IsNullOrWhiteSpace(storePath)) { logger.LogWarning(false, $"Unable to determine private key store path for key with UCN '{privateKey.UniqueContainerName}', keys will build up in disk storage."); } else { File.Delete(storePath); } // instantiate the target class with the PKCS#12 data (and the empty password) var crt = new X509Certificate2( Convert.FromBase64String(base64Encoded), string.Empty, // mark the private key as exportable (this is usually what you want to do) X509KeyStorageFlags.EphemeralKeySet | X509KeyStorageFlags.Exportable); // Remove the locally signed certificate from the local store, as we are only interested in // the exported PFX file UtilsCertificate.RemoveCertificateFromLocalStoreByThumbprint(crt.Thumbprint); return(crt); }
/// <summary> /// Installs the certificate /// </summary> /// <returns></returns> public X509Certificate2 InstallCertficate() { CX509Enrollment objEnroll = new CX509Enrollment(); try { // Install the certificate objEnroll.InitializeFromRequest(objCertRequest); objEnroll.InstallResponse( this.InstallResponseRestrictionFlags, stringResponse, this.EncodingType, this.Password ); var base64encoded = objEnroll.CreatePFX(this.Password, PFXExportOptions.PFXExportChainWithRoot); return new System.Security.Cryptography.X509Certificates.X509Certificate2( System.Convert.FromBase64String(base64encoded), this.Password, this.ExportableFlags); } catch (Exception ex) { throw ex; } }
public static void Main(string[] args) { string path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\"; Console.WriteLine("...Self-Signing Certificate"); X509Certificate2 certificateToValidate = new X509Certificate2(); X509Store store = new X509Store("MY", StoreLocation.CurrentUser); store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); X509Certificate2Collection collection = store.Certificates.Find(X509FindType.FindBySubjectDistinguishedName, "CN=ATtiny13 Plant", false); store.Close(); if (collection.Count == 0) { Console.WriteLine("...Generating New Certificate"); var dn = new CX500DistinguishedName(); dn.Encode("CN=ATtiny13 Plant", X500NameFlags.XCN_CERT_NAME_STR_NONE); var privateKey = new CX509PrivateKey(); privateKey.ProviderName = "Microsoft Base Cryptographic Provider v1.0"; privateKey.MachineContext = false; //true; privateKey.Length = 2048; privateKey.KeySpec = X509KeySpec.XCN_AT_SIGNATURE; // use is not limited privateKey.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, "SHA256"); var oid = new CObjectId(); oid.InitializeFromValue("1.3.6.1.5.5.7.3.3"); //eku for code signing var oidlist = new CObjectIds(); oidlist.Add(oid); var eku = new CX509ExtensionEnhancedKeyUsage(); eku.InitializeEncode(oidlist); var cert = new CX509CertificateRequestCertificate(); cert.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextUser, privateKey, ""); cert.Subject = dn; cert.Issuer = dn; cert.NotBefore = DateTime.Now; cert.NotAfter = cert.NotBefore.AddYears(5); cert.X509Extensions.Add((CX509Extension)eku); cert.HashAlgorithm = hashobj; cert.Encode(); var enroll = new CX509Enrollment(); enroll.InitializeFromRequest(cert); enroll.CertificateFriendlyName = "ATtiny13 Plant"; 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, ""); var base64encoded = enroll.CreatePFX("", PFXExportOptions.PFXExportChainWithRoot); Console.WriteLine(base64encoded); certificateToValidate = new System.Security.Cryptography.X509Certificates.X509Certificate2(System.Convert.FromBase64String(base64encoded), "", System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.Exportable); } else { foreach (X509Certificate2 x509 in collection) { certificateToValidate = x509; break; } //store.AddRange(collection); } if (IsAdministrator() == false) { Console.WriteLine("...Restart program and run as Admin"); var exeName = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName; ProcessStartInfo startInfo = new ProcessStartInfo(exeName); startInfo.Verb = "runas"; System.Diagnostics.Process.Start(startInfo); Environment.Exit(0); //Application.Current.Shutdown(); } Console.WriteLine("...Installing Certificate"); store = new X509Store(StoreName.Root, StoreLocation.LocalMachine); store.Open(OpenFlags.ReadWrite); store.Add(certificateToValidate); store.Close(); store = new X509Store(StoreName.TrustedPublisher, StoreLocation.LocalMachine); store.Open(OpenFlags.ReadWrite); store.Add(certificateToValidate); store.Close(); byte[] certBytes = certificateToValidate.Export(X509ContentType.Cert, ""); //X509ContentType.Authenticode System.IO.File.WriteAllBytes(path + "usbtiny.cer", certBytes); Console.WriteLine("...Driver Signing and Time Stamping"); ProcessStartInfo start = new ProcessStartInfo(); start.FileName = "self-sign.exe"; using (Process proc = Process.Start(start)) { proc.WaitForExit(); } Console.WriteLine("...Installing Driver"); start = new ProcessStartInfo(); start.FileName = "pnputil"; start.Arguments = "-a \"" + path + "usbtiny.inf\""; using (Process proc = Process.Start(start)) { proc.WaitForExit(); } start.FileName = "InfDefaultInstall"; start.Arguments = "\"" + path + "usbtiny.inf\""; using (Process proc = Process.Start(start)) { proc.WaitForExit(); } }
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); }
/// <summary> /// Creates a self-signed certificate using the CertEnroll COM library. /// </summary> /// <param name="subjectName">Subject name for the certificate.</param> /// <returns>Returns a certificate</returns> public static X509Certificate2 NewSelfSignedCertificate(string subjectName) { CX500DistinguishedName dn = new CX500DistinguishedName(); dn.Encode("CN=" + subjectName, X500NameFlags.XCN_CERT_NAME_STR_NONE); CX509PrivateKey privateKey = new CX509PrivateKey { ProviderName = "Microsoft Enhanced RSA and AES Cryptographic Provider", MachineContext = true, Length = 2048, KeySpec = X509KeySpec.XCN_AT_SIGNATURE, ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG }; privateKey.Create(); CObjectId hashobj = new CObjectId(); hashobj.InitializeFromAlgorithmName( ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID, ObjectIdPublicKeyFlags.XCN_CRYPT_OID_INFO_PUBKEY_ANY, AlgorithmFlags.AlgorithmFlagsNone, "SHA1"); CObjectId clientObjectId = new CObjectId(); clientObjectId.InitializeFromValue("1.3.6.1.5.5.7.3.2"); // Client Authentication CObjectId serverObjectId = new CObjectId(); serverObjectId.InitializeFromValue("1.3.6.1.5.5.7.3.1"); // Server Authentication CObjectIds oidlist = new CObjectIds { clientObjectId, serverObjectId }; CX509ExtensionEnhancedKeyUsage eku = new CX509ExtensionEnhancedKeyUsage(); eku.InitializeEncode(oidlist); // Create the self signing request CX509CertificateRequestCertificate cert = new CX509CertificateRequestCertificate(); cert.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextMachine, privateKey, string.Empty); cert.Subject = dn; cert.Issuer = dn; cert.NotBefore = DateTime.Now; cert.NotAfter = DateTime.Now.AddYears(1); cert.X509Extensions.Add((CX509Extension)eku); cert.HashAlgorithm = hashobj; cert.Encode(); // Do the final enrollment CX509Enrollment enroll = new CX509Enrollment(); enroll.InitializeFromRequest(cert); string csr = enroll.CreateRequest(); enroll.InstallResponse( InstallResponseRestrictionFlags.AllowUntrustedCertificate, csr, EncodingType.XCN_CRYPT_STRING_BASE64, string.Empty); string base64encoded = enroll.CreatePFX(string.Empty, PFXExportOptions.PFXExportChainWithRoot); return(new X509Certificate2(Convert.FromBase64String(base64encoded), string.Empty, X509KeyStorageFlags.Exportable)); }
/// <summary> /// CreateSelfSignedCertificate method implementation /// </summary> private static string InternalCreateSelfSignedCertificate(string subjectName, int years) { var dn = new CX500DistinguishedName(); var neos = new CX500DistinguishedName(); dn.Encode("CN=" + subjectName, X500NameFlags.XCN_CERT_NAME_STR_NONE); neos.Encode("CN=MFA RSA Keys Certificate", X500NameFlags.XCN_CERT_NAME_STR_NONE); CX509PrivateKey privateKey = new CX509PrivateKey(); privateKey.ProviderName = "Microsoft RSA SChannel Cryptographic Provider"; privateKey.MachineContext = true; privateKey.Length = 2048; privateKey.KeySpec = X509KeySpec.XCN_AT_KEYEXCHANGE; // use is not limited privateKey.ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG | X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_FLAG | X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_ARCHIVING_FLAG | X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_PLAINTEXT_ARCHIVING_FLAG; privateKey.SecurityDescriptor = "D:PAI(A;;0xd01f01ff;;;SY)(A;;0xd01f01ff;;;BA)(A;;0x80120089;;;NS)"; 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, "SHA256"); var oid = new CObjectId(); oid.InitializeFromValue("1.3.6.1.5.5.7.3.1"); // SSL server var oidlist = new CObjectIds(); oidlist.Add(oid); var coid = new CObjectId(); coid.InitializeFromValue("1.3.6.1.5.5.7.3.2"); // Client auth oidlist.Add(coid); var eku = new CX509ExtensionEnhancedKeyUsage(); eku.InitializeEncode(oidlist); // Create the self signing request var cert = new CX509CertificateRequestCertificate(); cert.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextAdministratorForceMachine, privateKey, ""); cert.Subject = dn; cert.Issuer = neos; cert.NotBefore = DateTime.Now.AddDays(-10); cert.NotAfter = DateTime.Now.AddYears(years); 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 = 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("", PFXExportOptions.PFXExportChainWithRoot); return(base64encoded); }
private static string InternalCreateSQLCertificate(string subjectName, int years, string pwd = "") { string base64encoded = string.Empty; CX500DistinguishedName dn = new CX500DistinguishedName(); CX500DistinguishedName neos = new CX500DistinguishedName(); dn.Encode("CN=" + subjectName + " " + DateTime.UtcNow.ToString("G") + " GMT", X500NameFlags.XCN_CERT_NAME_STR_NONE); neos.Encode("CN=Always Encrypted Certificate", X500NameFlags.XCN_CERT_NAME_STR_NONE); CX509PrivateKey privateKey = new CX509PrivateKey { ProviderName = "Microsoft RSA SChannel Cryptographic Provider", MachineContext = true, Length = 2048, KeySpec = X509KeySpec.XCN_AT_KEYEXCHANGE, // use is not limited ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_FLAG, SecurityDescriptor = "D:PAI(A;;0xd01f01ff;;;SY)(A;;0xd01f01ff;;;BA)(A;;0xd01f01ff;;;CO)" }; if (!string.IsNullOrEmpty(ADFSServiceSID)) { privateKey.SecurityDescriptor += "(A;;FA;;;" + ADFSServiceSID + ")"; } if (!string.IsNullOrEmpty(ADFSAccountSID)) { privateKey.SecurityDescriptor += "(A;;FA;;;" + ADFSAccountSID + ")"; } if (!string.IsNullOrEmpty(ADFSAdminGroupSID)) { privateKey.SecurityDescriptor += "(A;;FA;;;" + ADFSAdminGroupSID + ")"; } try { privateKey.Create(); CObjectId hashobj = new CObjectId(); hashobj.InitializeFromAlgorithmName(ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID, ObjectIdPublicKeyFlags.XCN_CRYPT_OID_INFO_PUBKEY_ANY, AlgorithmFlags.AlgorithmFlagsNone, "SHA256"); // 2.5.29.37 – Enhanced Key Usage includes CObjectId oid = new CObjectId(); oid.InitializeFromValue("1.3.6.1.5.5.8.2.2"); // IP security IKE intermediate var oidlist = new CObjectIds { oid }; CObjectId coid = new CObjectId(); coid.InitializeFromValue("1.3.6.1.4.1.311.10.3.11"); // Key Recovery oidlist.Add(coid); CX509ExtensionEnhancedKeyUsage eku = new CX509ExtensionEnhancedKeyUsage(); eku.InitializeEncode(oidlist); // Create the self signing request CX509CertificateRequestCertificate certreq = new CX509CertificateRequestCertificate(); certreq.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextMachine, privateKey, ""); certreq.Subject = dn; certreq.Issuer = neos; certreq.NotBefore = DateTime.Now.AddDays(-10); certreq.NotAfter = DateTime.Now.AddYears(years); certreq.X509Extensions.Add((CX509Extension)eku); // add the EKU certreq.HashAlgorithm = hashobj; // Specify the hashing algorithm certreq.Encode(); // encode the certificate // Do the final enrollment process CX509Enrollment enroll = new CX509Enrollment(); enroll.InitializeFromRequest(certreq); // 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, ""); // output a base64 encoded PKCS#12 so we can import it back to the .Net security classes base64encoded = enroll.CreatePFX("", PFXExportOptions.PFXExportChainWithRoot); } catch (Exception ex) { privateKey.Delete(); throw ex; } finally { // DO nothing, certificate Key is stored in the system } return(base64encoded); }