使用C#生成CSR并导出私钥

时间:2013-12-05 10:31:30

标签: c# ssl rsa private-key csr

我正在尝试编写代码来生成CSR并以编程方式使用C#导出其私钥。我发现this blog post(它几乎是唯一的一个)

使用以下代码,CSR和私钥可以生成并导出为Base64 Strings。此CSR也可以发布SSL证书。但是,导出的私钥有一些错误。我得到了“Key Modulus Hash:无法解码。密钥可能已损坏或格式不正确。”来自online tool

我希望你能证明我的错误,你可以节省我的一天。

class Program {

        private const int CC_DEFAULTCONFIG = 0;
        private const int CC_UIPICKCONFIG = 0x1;
        private const int CR_IN_BASE64 = 0x1;
        private const int CR_IN_FORMATANY = 0;
        private const int CR_IN_PKCS10 = 0x100;
        private const int CR_DISP_ISSUED = 0x3;
        private const int CR_DISP_UNDER_SUBMISSION = 0x5;
        private const int CR_OUT_BASE64 = 0x1;
        private const int CR_OUT_CHAIN = 0x100;
        static void Main(string[] args) {
            //  Create all the objects that will be required
            CX509CertificateRequestPkcs10 objPkcs10 = new CX509CertificateRequestPkcs10Class();
            CX509PrivateKey objPrivateKey = new CX509PrivateKeyClass();
            CCspInformation objCSP = new CCspInformationClass();
            CCspInformations objCSPs = new CCspInformationsClass();
            CX500DistinguishedName objDN = new CX500DistinguishedNameClass();
            CX509Enrollment objEnroll = new CX509EnrollmentClass();
            CObjectIds objObjectIds = new CObjectIdsClass();
            CObjectId objObjectId = new CObjectIdClass();
            CX509ExtensionKeyUsage objExtensionKeyUsage = new CX509ExtensionKeyUsageClass();
            CX509ExtensionEnhancedKeyUsage objX509ExtensionEnhancedKeyUsage = new CX509ExtensionEnhancedKeyUsageClass();
            string strRequest;

            try {


                //  Initialize the csp object using the desired Cryptograhic Service Provider (CSP)
                objCSP.InitializeFromName(
                    "Microsoft RSA SChannel Cryptographic Provider"
                );

                //  Add this CSP object to the CSP collection object
                objCSPs.Add(
                    objCSP
                );
                String date = DateTime.Now.ToString("MMddHHmmss") + DateTime.Now.Millisecond.ToString();
                //  Provide key container name, key length and key spec to the private key object
                objPrivateKey.ContainerName = "Company-" + date; 
                objPrivateKey.Length = 2048;
                objPrivateKey.ProviderName = "Microsoft RSA SChannel Cryptographic Provider";
                objPrivateKey.ProviderType = X509ProviderType.XCN_PROV_RSA_SCHANNEL;
                objPrivateKey.KeySpec = X509KeySpec.XCN_AT_KEYEXCHANGE;
                objPrivateKey.KeyUsage = X509PrivateKeyUsageFlags.XCN_NCRYPT_ALLOW_ALL_USAGES;

                objPrivateKey.MachineContext = false;

                //  Provide the CSP collection object (in this case containing only 1 CSP object)
                //  to the private key object
                objPrivateKey.CspInformations = objCSPs;
                objPrivateKey.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;

                //  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
                objPkcs10.InitializeFromPrivateKey(
                    X509CertificateEnrollmentContext.ContextUser,
                    objPrivateKey,
                    ""
                );

                // Key Usage Extension 
                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
                );
                objPkcs10.X509Extensions.Add((CX509Extension)objExtensionKeyUsage);

                // Enhanced Key Usage Extension
                objObjectId.InitializeFromValue("1.3.6.1.5.5.7.3.1"); // OID for Client Authentication usage
                objObjectIds.Add(objObjectId);
                objX509ExtensionEnhancedKeyUsage.InitializeEncode(objObjectIds);
                objPkcs10.X509Extensions.Add((CX509Extension)objX509ExtensionEnhancedKeyUsage);

                //  Encode the name in using the Distinguished Name object
                objDN.Encode(
                    "CN=www.mydomain.com, O=Company, OU=IT, C=TR, S=Istanbul;L=Istanbul, E=postmaster@mydomain.com",
                    X500NameFlags.XCN_CERT_NAME_STR_NONE
                );

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

                // Create enrollment request
                objEnroll.InitializeFromRequest(objPkcs10);

                strRequest = objEnroll.CreateRequest(
                    EncodingType.XCN_CRYPT_STRING_BASE64REQUESTHEADER
                );
                string key = objPrivateKey.Export("PUBLICBLOB", EncodingType.XCN_CRYPT_STRING_BASE64);
                File.WriteAllText("C:\\csr.txt", key);

                File.AppendAllText("C:\\csr.txt", strRequest);

            }
            catch(Exception ex) {
                Console.WriteLine(ex.Message);
                Console.ReadLine();
            }
        }
    }

0 个答案:

没有答案