我正在尝试编写代码来生成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();
}
}
}