Beispiel #1
3
        public string CreateRequest(string cn, string ou, string o, string l, string s, string c, string oid, int keylength)
        {
            var objCSPs = new CCspInformations();
                objCSPs.AddAvailableCsps();

                var objPrivateKey = new CX509PrivateKey();
                objPrivateKey.Length = keylength;
                objPrivateKey.KeySpec = X509KeySpec.XCN_AT_SIGNATURE;                                                             //http://msdn.microsoft.com/en-us/library/windows/desktop/aa379409(v=vs.85).aspx
                objPrivateKey.KeyUsage = X509PrivateKeyUsageFlags.XCN_NCRYPT_ALLOW_ALL_USAGES;                                    //http://msdn.microsoft.com/en-us/library/windows/desktop/aa379417(v=vs.85).aspx
                objPrivateKey.MachineContext = false;                                                                             //http://msdn.microsoft.com/en-us/library/windows/desktop/aa379024(v=vs.85).aspx
                objPrivateKey.ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_FLAG;                              //http://msdn.microsoft.com/en-us/library/windows/desktop/aa379412(v=vs.85).aspx
                objPrivateKey.CspInformations = objCSPs;
                objPrivateKey.Create();

                var objPkcs10 = new CX509CertificateRequestPkcs10();
                objPkcs10.InitializeFromPrivateKey(
                    X509CertificateEnrollmentContext.ContextUser,                                                                 //http://msdn.microsoft.com/en-us/library/windows/desktop/aa379399(v=vs.85).aspx
                    objPrivateKey,
                    string.Empty);

                var objExtensionKeyUsage = new CX509ExtensionKeyUsage();
                objExtensionKeyUsage.InitializeEncode(
                    CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_DIGITAL_SIGNATURE_KEY_USAGE |                                        // http://msdn.microsoft.com/en-us/library/windows/desktop/aa379410(v=vs.85).aspx
                    CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_NON_REPUDIATION_KEY_USAGE |                                            // http://msdn.microsoft.com/en-us/library/windows/desktop/aa379410(v=vs.85).aspx
                    CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_KEY_ENCIPHERMENT_KEY_USAGE |                                        // http://msdn.microsoft.com/en-us/library/windows/desktop/aa379410(v=vs.85).aspx
                    CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_DATA_ENCIPHERMENT_KEY_USAGE);                                       // http://msdn.microsoft.com/en-us/library/windows/desktop/aa379410(v=vs.85).aspx
            objPkcs10.X509Extensions.Add((CX509Extension)objExtensionKeyUsage);

                var objObjectId = new CObjectId();
                var objObjectIds = new CObjectIds();
                var objX509ExtensionEnhancedKeyUsage = new CX509ExtensionEnhancedKeyUsage();
                //objObjectId.InitializeFromValue("1.3.6.1.5.5.7.3.1");
                objObjectId.InitializeFromValue(oid);                                                                           //Some info about OIDS: http://www.alvestrand.no/objectid/1.3.6.1.5.5.7.3.html
                objObjectIds.Add(objObjectId);
                objX509ExtensionEnhancedKeyUsage.InitializeEncode(objObjectIds);
                objPkcs10.X509Extensions.Add((CX509Extension)objX509ExtensionEnhancedKeyUsage);

                // TODO: Create CERTS with SAN: http://msdn.microsoft.com/en-us/library/windows/desktop/aa378081(v=vs.85).aspx

            /*
                var test3 = new CX509ExtensionAlternativeNames();
                var test4 = new CAlternativeName();
            var test2 = new CAlternativeNames();

                test4.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME,"CRAP.no");
                test2.Add(test4);
                 test3.InitializeEncode(test2);
                */

                //objPkcs10.X509Extensions.Add((CX509Extension));

                var objDN = new CX500DistinguishedName();
                var subjectName = "CN = " + cn + ",OU = " + ou + ",O = " + o + ",L = " + l + ",S = " + s + ",C = " + c;

                objDN.Encode(subjectName, X500NameFlags.XCN_CERT_NAME_STR_NONE);                                                //http://msdn.microsoft.com/en-us/library/windows/desktop/aa379394(v=vs.85).aspx
                objPkcs10.Subject = objDN;

                var objEnroll = new CX509Enrollment();
                objEnroll.InitializeFromRequest(objPkcs10);
                var strRequest = objEnroll.CreateRequest(EncodingType.XCN_CRYPT_STRING_BASE64);                                 //http://msdn.microsoft.com/en-us/library/windows/desktop/aa374936(v=vs.85).aspx

                return strRequest;
        }
Beispiel #2
0
        public CX509PrivateKey GeneratePrivateKey(int KeyLength)
        {
            try
            {
                CCspInformations objCSPs = new CCspInformations();
                objCSPs.AddAvailableCsps();

                // 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          = KeyLength;
                privateKey.KeySpec         = X509KeySpec.XCN_AT_SIGNATURE;
                privateKey.KeyUsage        = X509PrivateKeyUsageFlags.XCN_NCRYPT_ALLOW_ALL_USAGES;
                privateKey.ExportPolicy    = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG;
                privateKey.CspInformations = objCSPs;

                //privateKey.ExportPolicy =
                //X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_ARCHIVING_FLAG |
                //X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_FLAG |
                //X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_PLAINTEXT_ARCHIVING_FLAG |
                //X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG;

                privateKey.Create();

                return(privateKey);
            }
            catch (Exception ex)
            {
                return(null);
            }
        }
Beispiel #3
0
        internal static Pkcs10CertificationRequest createKeyPair()
        {
            var objCSPs = new CCspInformations();

            objCSPs.AddAvailableCsps();


            var objPrivateKey = new CX509PrivateKey();

            objPrivateKey.Length          = 1024;
            objPrivateKey.KeySpec         = X509KeySpec.XCN_AT_SIGNATURE;
            objPrivateKey.KeyUsage        = X509PrivateKeyUsageFlags.XCN_NCRYPT_ALLOW_ALL_USAGES;
            objPrivateKey.MachineContext  = false;
            objPrivateKey.ExportPolicy    = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_FLAG;
            objPrivateKey.CspInformations = objCSPs;
            objPrivateKey.Create();

            var objPkcs10 = new CX509CertificateRequestPkcs10();

            objPkcs10.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextUser,
                                               objPrivateKey,
                                               string.Empty);

            //var objExtensionKeyUsage = new CX509ExtensionKeyUsage();
            //objExtensionKeyUsage.InitializeEncode(
            //    CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_KEY_CERT_SIGN_KEY_USAGE |
            //    CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_CRL_SIGN_KEY_USAGE);

            //objPkcs10.X509Extensions.Add((CX509Extension)objExtensionKeyUsage);

            //var objObjectId = new CObjectId();
            //var objObjectIds = new CObjectIds();
            //var objX509ExtensionEnhancedKeyUsage = new CX509ExtensionEnhancedKeyUsage();
            //objObjectId.InitializeFromValue("1.3.6.1.5.5.7.3.2");
            //objObjectIds.Add(objObjectId);
            //objX509ExtensionEnhancedKeyUsage.InitializeEncode(objObjectIds);
            //objPkcs10.X509Extensions.Add((CX509Extension)objX509ExtensionEnhancedKeyUsage);

            var objDN       = new CX500DistinguishedName();
            var subjectName = "CN = shaunxu.me, OU = ADCS, O = Blog, L = Beijng, S = Beijing, C = CN";

            objDN.Encode(subjectName, X500NameFlags.XCN_CERT_NAME_STR_NONE);
            objPkcs10.Subject = objDN;

            var objEnroll = new CX509Enrollment();

            objEnroll.InitializeFromRequest(objPkcs10);
            var strRequest = objEnroll.CreateRequest(EncodingType.XCN_CRYPT_STRING_BASE64);

            Pkcs10CertificationRequest p10 = new Pkcs10CertificationRequest(Convert.FromBase64String(strRequest));

            return(p10);
        }
Beispiel #4
0
        public static CspObject[] EnumProviders()
        {
            if (!CryptographyUtils.TestCNGCompat())
            {
                throw new PlatformNotSupportedException();
            }
            var csps = new CCspInformations();

            csps.AddAvailableCsps();

            return((from ICspInformation csp in csps select new CspObject(csp)).ToArray());
        }
Beispiel #5
0
        public static CspProviderInfoCollection GetProviderInfo()
        {
            if (!CryptographyUtils.TestCNGCompat())
            {
                throw new PlatformNotSupportedException();
            }

            var csps = new CCspInformations();

            csps.AddAvailableCsps();
            var retValue = new CspProviderInfoCollection();

            retValue.AddRange((from ICspInformation csp in csps select new CspProviderInfo(csp)).ToArray());
            CryptographyUtils.ReleaseCom(csps);
            return(retValue);
        }
Beispiel #6
0
        /// <summary>
        /// Gets named registered Cryptographic Service Provider (CSP) or Key Storage Provider (KSP), its
        /// information and supported cryptographic algorithms.
        /// </summary>
        /// <param name="name">Cryptographic provider name.</param>
        /// <exception cref="PlatformNotSupportedException">
        /// Current platform does not support key storage providers (prior to Windows Vista).
        /// </exception>
        /// <returns>Specified provider information. Method returns null if provider is not found.</returns>
        public static CspProviderInfo GetProviderInfo(String name)
        {
            if (!CryptographyUtils.TestCNGCompat())
            {
                throw new PlatformNotSupportedException();
            }
            var providers = new CCspInformations();

            providers.AddAvailableCsps();
            try {
                ICspInformation provider = providers.ItemByName[name];
                return(new CspProviderInfo(provider));
            } catch {
                return(null);
            }
        }
Beispiel #7
0
        static void Main(string[] args)
        {
            var providers = new CCspInformations();

            providers.AddAvailableCsps();
            int i = 0;

            foreach (var providerInfo in providers.OfType <CCspInformation>())
            {
                Console.WriteLine("{0} {1}: {2}",
                                  i++
                                  , providerInfo.LegacyCsp ? "LEGACY" : "CNG"
                                  , providerInfo.Name);
            }
            Console.WriteLine("\n\nHit any key to continue: ");
            Console.ReadKey();
        }
Beispiel #8
0
        public static CspProviderInfoCollection GetProviderInfo(String name)
        {
            if (!CryptographyUtils.TestCNGCompat())
            {
                throw new PlatformNotSupportedException();
            }

            var csps = new CCspInformations();

            csps.AddAvailableCsps();
            var retValue = new CspProviderInfoCollection {
                new CspProviderInfo(csps.ItemByName[name])
            };

            CryptographyUtils.ReleaseCom(csps);
            return(retValue);
        }
        public string CreateTemplateRequest(string cn, string ou, string o, string l, string s, string c,
                                            int keyLength,
                                            string templateName)
        {
            var csp = new CCspInformations();

            csp.AddAvailableCsps();
            var privateKey = new CX509PrivateKey();

            privateKey.Length          = keyLength;
            privateKey.KeySpec         = X509KeySpec.XCN_AT_SIGNATURE;
            privateKey.KeyUsage        = X509PrivateKeyUsageFlags.XCN_NCRYPT_ALLOW_ALL_USAGES;
            privateKey.MachineContext  = false;
            privateKey.ExportPolicy    = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_FLAG;
            privateKey.CspInformations = csp;
            privateKey.Create();

            var pkcs10 = new CX509CertificateRequestPkcs10();

            pkcs10.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextUser,
                                            privateKey,
                                            templateName);

            var san = GetSAN(cn);

            pkcs10.X509Extensions.Add((CX509Extension)san);

            var distinguishedName = new CX500DistinguishedName();

            var subjectName = $"{cn},OU = {ou},O = {o} ,L = {l},S = {s},C = {c}";

            distinguishedName.Encode(subjectName);
            pkcs10.Subject = distinguishedName;

            var enroll = new CX509Enrollment();

            enroll.InitializeFromRequest(pkcs10);
            var strRequest = enroll.CreateRequest(EncodingType.XCN_CRYPT_STRING_BASE64HEADER);

            return(strRequest);
        }
        /// <summary>
        /// The create active directory certificate request.
        /// </summary>
        /// <param name="templateName">
        /// The template name.
        /// </param>
        /// <returns>
        /// The <see cref="string"/>.
        /// </returns>
        public string CreateActiveDirectoryCertificateRequest(string templateName)
        {
            //// https://blogs.msdn.microsoft.com/alejacma/2008/09/05/how-to-create-a-certificate-request-with-certenroll-and-net-c/
            //// http://geekswithblogs.net/shaunxu/archive/2012/01/13/working-with-active-directory-certificate-service-via-c.aspx

            this.LastError.Clear();
            try
            {
                var cspInformations = new CCspInformations();
                cspInformations.AddAvailableCsps();

                var privateKey = new CX509PrivateKey // Создали приватный ключ
                {
                    Length          = 2048,
                    KeySpec         = X509KeySpec.XCN_AT_SIGNATURE,
                    KeyUsage        = X509PrivateKeyUsageFlags.XCN_NCRYPT_ALLOW_ALL_USAGES,
                    MachineContext  = false,
                    ExportPolicy    = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_FLAG,
                    CspInformations = cspInformations
                };

                privateKey.Create();

                var objPkcs10 = new CX509CertificateRequestPkcs10();
                objPkcs10.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextUser, privateKey, templateName);
                var objEnroll = new CX509Enrollment();
                objEnroll.InitializeFromRequest(objPkcs10);
                var strRequest = objEnroll.CreateRequest(); // Значение по уолчанию: EncodingType.XCN_CRYPT_STRING_BASE64
                return(strRequest);
            }
            catch (Exception ex)
            {
                this.LastError.Add(ex.Message);
                return(string.Empty);
            }
        }
Beispiel #11
0
        public string CreateTemplateRequest(string cn, string ou, string o, string l, string s, string c, int keylength, string template)
        {
            var objCSPs = new CCspInformations();
                objCSPs.AddAvailableCsps();
                var objPrivateKey = new CX509PrivateKey();
                objPrivateKey.Length = keylength;
                objPrivateKey.KeySpec = X509KeySpec.XCN_AT_SIGNATURE;
                objPrivateKey.KeyUsage = X509PrivateKeyUsageFlags.XCN_NCRYPT_ALLOW_ALL_USAGES;
                objPrivateKey.MachineContext = false;
                objPrivateKey.ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_FLAG;
                objPrivateKey.CspInformations = objCSPs;
                objPrivateKey.Create();

                var objPkcs10 = new CX509CertificateRequestPkcs10();
                objPkcs10.InitializeFromPrivateKey(
                    X509CertificateEnrollmentContext.ContextUser,
                    objPrivateKey,
                    template);

                var objDN = new CX500DistinguishedName();

                var subjectName = "CN = " + cn + ",OU = " + ou + ",O = " + o + ",L = " + l + ",S = " + s + ",C = " + c;
                objDN.Encode(subjectName, X500NameFlags.XCN_CERT_NAME_STR_NONE);
                objPkcs10.Subject = objDN;

                var objEnroll = new CX509Enrollment();
                objEnroll.InitializeFromRequest(objPkcs10);
                var strRequest = objEnroll.CreateRequest(EncodingType.XCN_CRYPT_STRING_BASE64);

                return strRequest;
        }
Beispiel #12
0
            /// <summary>
            /// Function used to create a certificate signing request using the OS.
            /// Note that this function will place a certificate in the "Certificate Enrollment Requests" folder
            /// of the certificate store specified in loc. You can view this by running either
            /// certmgr or mmc from the command line.
            /// </summary>
            /// <param name="loc">Location to put certificate</param>
            /// <param name="subject_line">The subject line of the certificate, fields should be ; seperated, i.e.: "C=US; ST=Minnesota; L=Eden Prairie; O=Forward Pay Systems, Inc.; OU=Forward Pay; CN=fps.com"</param>
            /// <returns>The certificate signing request, if successful in PEM format</returns>
            public string GenerateRequest()
            {
                //code originally came from: http://blogs.msdn.com/b/alejacma/archive/2008/09/05/how-to-create-a-certificate-request-with-certenroll-and-net-c.aspx
                //modified version of it is here: http://stackoverflow.com/questions/16755634/issue-generating-a-csr-in-windows-vista-cx509certificaterequestpkcs10
                //here is the standard for certificates: http://www.ietf.org/rfc/rfc3280.txt


                //the PKCS#10 certificate request (http://msdn.microsoft.com/en-us/library/windows/desktop/aa377505.aspx)
                CX509CertificateRequestPkcs10 objPkcs10 = new CX509CertificateRequestPkcs10();

                //assymetric private key that can be used for encryption (http://msdn.microsoft.com/en-us/library/windows/desktop/aa378921.aspx)
                CX509PrivateKey objPrivateKey = new CX509PrivateKey();

                //access to the general information about a cryptographic provider (http://msdn.microsoft.com/en-us/library/windows/desktop/aa375967.aspx)
                CCspInformation objCSP = new CCspInformation();

                //collection on cryptographic providers available: http://msdn.microsoft.com/en-us/library/windows/desktop/aa375967(v=vs.85).aspx
                CCspInformations objCSPs = new CCspInformations();

                CX500DistinguishedName objDN = new CX500DistinguishedName();

                //top level object that enables installing a certificate response http://msdn.microsoft.com/en-us/library/windows/desktop/aa377809.aspx
                CX509Enrollment                objEnroll                        = new CX509Enrollment();
                CObjectIds                     objObjectIds                     = new CObjectIds();
                CObjectId                      objObjectId                      = new CObjectId();
                CObjectId                      objObjectId2                     = new CObjectId();
                CX509ExtensionKeyUsage         objExtensionKeyUsage             = new CX509ExtensionKeyUsage();
                CX509ExtensionEnhancedKeyUsage objX509ExtensionEnhancedKeyUsage = new CX509ExtensionEnhancedKeyUsage();

                string csr_pem = null;

                //  Initialize the csp object using the desired Cryptograhic Service Provider (CSP)

                objCSPs.AddAvailableCsps();

                //Provide key container name, key length and key spec to the private key object
                objPrivateKey.ProviderName = providerName;
                objPrivateKey.Length       = KeyLength;
                objPrivateKey.KeySpec      = X509KeySpec.XCN_AT_KEYEXCHANGE; //Must flag as XCN_AT_KEYEXCHANGE to use this certificate for exchanging symmetric keys (needed for most SSL cipher suites)
                objPrivateKey.KeyUsage     = X509PrivateKeyUsageFlags.XCN_NCRYPT_ALLOW_ALL_USAGES;
                if (Location == StoreLocation.LocalMachine)
                {
                    objPrivateKey.MachineContext = true;
                }
                else
                {
                    objPrivateKey.MachineContext = false;                                               //must set this to true if installing to the local machine certificate store
                }
                objPrivateKey.ExportPolicy    = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_FLAG; //must set this if we want to be able to export it later. (for WinSIP maybe we don't want to be able to ever export the key??)
                objPrivateKey.CspInformations = objCSPs;

                //  Create the actual key pair
                objPrivateKey.Create();

                //  Initialize the PKCS#10 certificate request object based on the private key.
                //  Using the context, indicate that this is a user certificate request and don't
                //  provide a template name
                if (Location == StoreLocation.LocalMachine)
                {
                    objPkcs10.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextMachine, objPrivateKey, "");
                }
                else
                {
                    objPkcs10.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextUser, objPrivateKey, "");
                }

                //Set has to sha256
                CObjectId hashobj = new CObjectId();

                hashobj.InitializeFromAlgorithmName(ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID, ObjectIdPublicKeyFlags.XCN_CRYPT_OID_INFO_PUBKEY_ANY, AlgorithmFlags.AlgorithmFlagsNone, "SHA256");
                objPkcs10.HashAlgorithm = hashobj;

                // Key Usage Extension -- we only need digital signature and key encipherment for TLS:
                //  NOTE: in openSSL, I didn't used to request any specific extensions. Instead, I let the CA add them
                objExtensionKeyUsage.InitializeEncode(
                    CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_DIGITAL_SIGNATURE_KEY_USAGE |
                    CERTENROLLLib.X509KeyUsageFlags.XCN_CERT_KEY_ENCIPHERMENT_KEY_USAGE
                    );
                objPkcs10.X509Extensions.Add((CX509Extension)objExtensionKeyUsage);

                // Enhanced Key Usage Extension
                objObjectId.InitializeFromValue("1.3.6.1.5.5.7.3.1");  // OID for Server Authentication usage (see this: http://stackoverflow.com/questions/17477279/client-authentication-1-3-6-1-5-5-7-3-2-oid-in-server-certificates)
                objObjectId2.InitializeFromValue("1.3.6.1.5.5.7.3.2"); // OID for Client Authentication usage (see this: http://stackoverflow.com/questions/17477279/client-authentication-1-3-6-1-5-5-7-3-2-oid-in-server-certificates)
                objObjectIds.Add(objObjectId);
                objObjectIds.Add(objObjectId2);
                objX509ExtensionEnhancedKeyUsage.InitializeEncode(objObjectIds);
                objPkcs10.X509Extensions.Add((CX509Extension)objX509ExtensionEnhancedKeyUsage);

                //  Encode the name in using the Distinguished Name object
                // see here: http://msdn.microsoft.com/en-us/library/windows/desktop/aa379394(v=vs.85).aspx

                /*objDN.Encode(
                 *  "C=US, ST=Minnesota, L=Eden Prairie, O=Forward Pay Systems; Inc., OU=Forward Pay, CN=ERIC_CN",
                 *  X500NameFlags.XCN_CERT_NAME_STR_NONE
                 * );*/
                objDN.Encode(
                    Subject,
                    X500NameFlags.XCN_CERT_NAME_STR_SEMICOLON_FLAG
                    ); //"C=US; ST=Minnesota; L=Eden Prairie; O=Forward Pay Systems, Inc.; OU=Forward Pay; CN=ERIC_CN"

                //  Assing the subject name by using the Distinguished Name object initialized above
                objPkcs10.Subject = objDN;

                //suppress extra attributes:
                objPkcs10.SuppressDefaults = true;

                // Create enrollment request
                objEnroll.InitializeFromRequest(objPkcs10);
                csr_pem = objEnroll.CreateRequest(
                    EncodingType.XCN_CRYPT_STRING_BASE64
                    );
                csr_pem = "-----BEGIN CERTIFICATE REQUEST-----\r\n" + csr_pem + "-----END CERTIFICATE REQUEST-----";

                return(csr_pem);
            }
        public string CreateRequest(string cn, string ou, string o, string l, string s, string c,
                                    string oid,
                                    int keyLength)
        {
            var csp = new CCspInformations();

            csp.AddAvailableCsps();

            var privateKey =
                (IX509PrivateKey)Activator.CreateInstance(Type.GetTypeFromProgID("X509Enrollment.CX509PrivateKey"));

            privateKey.Length          = keyLength;
            privateKey.KeySpec         = X509KeySpec.XCN_AT_SIGNATURE;
            privateKey.KeyUsage        = X509PrivateKeyUsageFlags.XCN_NCRYPT_ALLOW_ALL_USAGES;
            privateKey.MachineContext  = false;
            privateKey.ExportPolicy    = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_FLAG;
            privateKey.CspInformations = csp;
            privateKey.Create();

            var pkcs10 =
                (CX509CertificateRequestPkcs10)
                Activator.CreateInstance(Type.GetTypeFromProgID("X509Enrollment.CX509CertificateRequestPkcs10"));

            pkcs10.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextUser,
                                            privateKey,
                                            string.Empty);

            var extensionKeyUsage =
                (CX509ExtensionKeyUsage)
                Activator.CreateInstance(Type.GetTypeFromProgID("X509Enrollment.CX509ExtensionKeyUsage"));

            extensionKeyUsage.InitializeEncode(X509KeyUsageFlags.XCN_CERT_DIGITAL_SIGNATURE_KEY_USAGE |
                                               X509KeyUsageFlags.XCN_CERT_NON_REPUDIATION_KEY_USAGE |
                                               X509KeyUsageFlags.XCN_CERT_KEY_ENCIPHERMENT_KEY_USAGE |
                                               X509KeyUsageFlags.XCN_CERT_DATA_ENCIPHERMENT_KEY_USAGE);
            pkcs10.X509Extensions.Add((CX509Extension)extensionKeyUsage);

            var objectId  = new CObjectId();
            var objectIds = new CObjectIds();

            var extensionEnhancedKeyUsage =
                (CX509ExtensionEnhancedKeyUsage)
                Activator.CreateInstance(Type.GetTypeFromProgID("X509Enrollment.CX509ExtensionEnhancedKeyUsage"));

            objectId.InitializeFromValue(oid);
            objectIds.Add(objectId);
            extensionEnhancedKeyUsage.InitializeEncode(objectIds);
            pkcs10.X509Extensions.Add((CX509Extension)extensionEnhancedKeyUsage);

            var san = GetSAN(cn);

            pkcs10.X509Extensions.Add((CX509Extension)san);

            var distinguishedName =
                (CX500DistinguishedName)
                Activator.CreateInstance(Type.GetTypeFromProgID("X509Enrollment.CX500DistinguishedName"));

            cn = ConvertCn(cn);

            var subjectName = $"{cn},OU = {ou},O = {o} ,L = {l},S = {s},C = {c}";

            distinguishedName.Encode(subjectName);
            pkcs10.Subject = distinguishedName;

            var enroll =
                (CX509Enrollment)Activator.CreateInstance(Type.GetTypeFromProgID("X509Enrollment.CX509Enrollment"));

            enroll.InitializeFromRequest(pkcs10);
            var request = enroll.CreateRequest(EncodingType.XCN_CRYPT_STRING_BASE64HEADER);

            return(request);
        }