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); }
private void oGenerateButton_Click(object sender, RoutedEventArgs e) { CertEnroll.CCspInformation oProviderInfo = new CertEnroll.CCspInformation(); oProviderInfo.InitializeFromName(SelectedProvider); // create DN for subject and issuer CertEnroll.CX500DistinguishedName oSubjectDistinguishedName = new CertEnroll.CX500DistinguishedName(); oSubjectDistinguishedName.Encode("CN=" + oSubjectTextBox.Text, CertEnroll.X500NameFlags.XCN_CERT_NAME_STR_NONE); // create CN for subject and issuer CertEnroll.CX500DistinguishedName oIssuerDistinguishedName = new CertEnroll.CX500DistinguishedName(); oIssuerDistinguishedName.Encode("CN=" + oIssuerTextBox.Text, CertEnroll.X500NameFlags.XCN_CERT_NAME_STR_NONE); // create a new private key for the certificate CertEnroll.IX509PrivateKey oPrivateKey = (CertEnroll.IX509PrivateKey)Activator.CreateInstance(Type.GetTypeFromProgID("X509Enrollment.CX509PrivateKey")); try { oPrivateKey.ProviderName = (string)oProviderComboBox.SelectedValue; oPrivateKey.Algorithm = oProviderInfo.CspAlgorithms.ItemByName[ oSignatureComboBox.SelectedValue.ToString()].GetAlgorithmOid(0, CertEnroll.AlgorithmFlags.AlgorithmFlagsNone); oPrivateKey.MachineContext = oCertificateStoreMachineRadio.IsChecked.Value; oPrivateKey.Length = Convert.ToInt32(oKeyLengthTextBox.Text); oPrivateKey.KeyProtection = (oPasswordProtectCheckbox.IsChecked.Value) ? CertEnroll.X509PrivateKeyProtection.XCN_NCRYPT_UI_PROTECT_KEY_FLAG : CertEnroll.X509PrivateKeyProtection.XCN_NCRYPT_UI_NO_PROTECTION_FLAG; oPrivateKey.ExportPolicy = (oKeyExportableCheckbox.IsChecked.Value) ? (CertEnroll.X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG | CertEnroll.X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_FLAG) : CertEnroll.X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_NONE; oPrivateKey.Create(); } catch (Exception eError) { // note to the user the creation failed MessageBox.Show(this, "Certificate private key could not be constructed. This is often " + "due to an invalid set of parameters being selected that is not supported by the " + "cryptographic provider. The specific error message returned is below: " + Environment.NewLine + Environment.NewLine + eError.Message, "Creation Failed", MessageBoxButton.OK, MessageBoxImage.Error); return; } // set the signature mechanism for the certificate CertEnroll.CObjectId oHash = oProviderInfo.CspAlgorithms.ItemByName[SelectedHash].GetAlgorithmOid(0, CertEnroll.AlgorithmFlags.AlgorithmFlagsNone); // create a certificate request with the requested info CertEnroll.CX509CertificateRequestCertificate oCertRequestInfo = new CertEnroll.CX509CertificateRequestCertificate(); oCertRequestInfo.InitializeFromPrivateKey(CertEnroll.X509CertificateEnrollmentContext.ContextUser, oPrivateKey, ""); oCertRequestInfo.Subject = oSubjectDistinguishedName; oCertRequestInfo.Issuer = oIssuerDistinguishedName; oCertRequestInfo.NotBefore = oValidFromDatePicker.SelectedDate.Value; oCertRequestInfo.NotAfter = oValidUntilDatePicker.SelectedDate.Value; oCertRequestInfo.HashAlgorithm = oHash; // translate the list to a list that the enrollment will understand key a list of key // usages to use if (EnhancedKeyUsages.Where(k => k.Selected).Count() > 0) { CertEnroll.CObjectIds oKeyUsagesToAdd = new CertEnroll.CObjectIds(); foreach (EkuOption oKeyUsage in EnhancedKeyUsages.Where(k => k.Selected)) { CertEnroll.CObjectId oOID = new CertEnroll.CObjectId(); oOID.InitializeFromValue(oKeyUsage.Oid); oKeyUsagesToAdd.Add(oOID); } CertEnroll.CX509ExtensionEnhancedKeyUsage oKeyUsageList = new CertEnroll.CX509ExtensionEnhancedKeyUsage(); oKeyUsageList.InitializeEncode(oKeyUsagesToAdd); oCertRequestInfo.X509Extensions.Add((CertEnroll.CX509Extension)oKeyUsageList); } // create an enrollment request oCertRequestInfo.Encode(); CertEnroll.CX509Enrollment oEnrollRequest = new CertEnroll.CX509Enrollment(); oEnrollRequest.InitializeFromRequest(oCertRequestInfo); // install certificate into selected certificate store if (oCertificateSelfSignedRadio.IsChecked.Value) { string sCertRequestString = oEnrollRequest.CreateRequest(); oEnrollRequest.InstallResponse(CertEnroll.InstallResponseRestrictionFlags.AllowUntrustedCertificate, sCertRequestString, CertEnroll.EncodingType.XCN_CRYPT_STRING_BASE64, ""); } // produce request file else { // ask the user where to store the file SaveFileDialog oSaveDialog = new SaveFileDialog() { Filter = "Certificate Request (*.csr)|*.csr|All Files (*.*)|*.*", AddExtension = true, ValidateNames = true }; if (!oSaveDialog.ShowDialog(this).Value) { return; } // write the file string sCertRequestString = oEnrollRequest.CreateRequest(CertEnroll.EncodingType.XCN_CRYPT_STRING_BASE64REQUESTHEADER); System.IO.File.WriteAllText(oSaveDialog.FileName, sCertRequestString, Encoding.ASCII); } // note to the user the create was successful MessageBox.Show(this, "Certificate successfully created.", "Creation Successful", MessageBoxButton.OK, MessageBoxImage.Information); }