예제 #1
0
        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);
        }
예제 #2
0
        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);
        }