使用 .NET 从 inf 文件生成 CSR
Generating a CSR from an inf file using .NET
我正在使用如下所示的 INF 文件生成带有 "certreq.exe -new -q request.inf request.csr":
的 CSR
[Version]
Signature= "$Windows NT$"
[NewRequest]
Subject = "CN=subject"
KeyLength = 2048
Exportable = TRUE
MachineKeySet = TRUE
SMIME = FALSE
PrivateKeyArchive = FALSE
UserProtected = FALSE
UseExistingKeySet = FALSE
ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
ProviderType = 12
RequestType = CMC
KeyUsage = 0xa0
KeyAlgorithm = RSA
HashAlgorithm = sha256
[EnhancedKeyUsageExtension]
OID=1.3.6.1.5.5.7.3.1
有没有一种方法可以通过 .NET 执行此操作类,并且最好不必在 CSR 生成后将其导出到文件中?
非常感谢您的帮助。
因此,一种方法是使用 CertEnroll
。 CertEnroll 无法像上面的示例一样处理 INF 文件,这是 certreq 所独有的(尽管没有什么可以阻止您自己解析 INF)。
CertEnroll 是一个 COM 库,但仍然很容易在 .NET 中使用。首先,添加对它的引用。添加 COM 引用有点不同。但请注意,CertEnroll 在 Windows XP 或 Windows Vista 上不可用。
首先,在您的项目中,右键单击 "References" 和 select 添加引用。在"COM"菜单下,select"CertEnroll 1.0 Type Library".
功能的核心是 CX509CertificateRequestCmc
界面。 C# 中的 COM 接口有点特殊,你可以 "new" 它们,所以这是完全有效的:
var req = new CX509CertificateRequestCmc();
因此,要将您的 INF 转换为 CertEnroll,我认为它看起来类似于:
var req = new CX509CertificateRequestPkcs10();
req.Initialize(X509CertificateEnrollmentContext.ContextUser);
//Set basic constraints
var basicConstraints = new CX509ExtensionBasicConstraints();
basicConstraints.InitializeEncode(false, 0);
req.X509Extensions.Add((CX509Extension)basicConstraints);
//Set the hash algorithm
var hashAlgorithm = new CObjectId();
hashAlgorithm.InitializeFromAlgorithmName(ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID, 0, 0, "sha256");
req.HashAlgorithm = hashAlgorithm;
//Set the enhanced key usage
var eku = new CX509ExtensionEnhancedKeyUsage();
var serverAuth = new CObjectId();
serverAuth.InitializeFromValue("1.3.6.1.5.5.7.3.1");
var oids = new CObjectIds();
oids.Add(serverAuth);
eku.InitializeEncode(oids);
eku.Critical = false;
var privateKey = req.PrivateKey;
//Allow export as the INF does
privateKey.ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_FLAG;
privateKey.Length = 2048;
//Set the algorithm explicitly
var rsa = new CObjectId();
rsa.InitializeFromAlgorithmName(ObjectIdGroupId.XCN_CRYPT_ANY_GROUP_ID, 0, 0, "RSA");
privateKey.Algorithm = rsa;
privateKey.ProviderName = "Microsoft RSA SChannel Cryptographic Provider";
privateKey.ProviderType = X509ProviderType.XCN_PROV_RSA_SCHANNEL; //12
privateKey.KeyUsage = (X509PrivateKeyUsageFlags)0xA0;
privateKey.Existing = false;
privateKey.KeyProtection = X509PrivateKeyProtection.XCN_NCRYPT_UI_NO_PROTECTION_FLAG;
privateKey.MachineContext = true;
var dn = new CX500DistinguishedName();
dn.Encode("CN=subject", X500NameFlags.XCN_CERT_NAME_STR_NONE);
req.Subject = dn;
var cmc = new CX509CertificateRequestCmc();
cmc.InitializeFromInnerRequest(req);
cmc.ArchivePrivateKey = false;
cmc.Encode();
var data = cmc.RawData[EncodingType.XCN_CRYPT_STRING_BASE64REQUESTHEADER];
Console.WriteLine(data);
末尾的 "data" 变量包含请求,所有请求都没有保存到磁盘。
这里很可能缺少某些东西,但它确实会生成证书请求。我会咨询 CertEnroll documentation 以了解需要进行的任何进一步调整。
我正在使用如下所示的 INF 文件生成带有 "certreq.exe -new -q request.inf request.csr":
的 CSR[Version]
Signature= "$Windows NT$"
[NewRequest]
Subject = "CN=subject"
KeyLength = 2048
Exportable = TRUE
MachineKeySet = TRUE
SMIME = FALSE
PrivateKeyArchive = FALSE
UserProtected = FALSE
UseExistingKeySet = FALSE
ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
ProviderType = 12
RequestType = CMC
KeyUsage = 0xa0
KeyAlgorithm = RSA
HashAlgorithm = sha256
[EnhancedKeyUsageExtension]
OID=1.3.6.1.5.5.7.3.1
有没有一种方法可以通过 .NET 执行此操作类,并且最好不必在 CSR 生成后将其导出到文件中?
非常感谢您的帮助。
因此,一种方法是使用 CertEnroll
。 CertEnroll 无法像上面的示例一样处理 INF 文件,这是 certreq 所独有的(尽管没有什么可以阻止您自己解析 INF)。
CertEnroll 是一个 COM 库,但仍然很容易在 .NET 中使用。首先,添加对它的引用。添加 COM 引用有点不同。但请注意,CertEnroll 在 Windows XP 或 Windows Vista 上不可用。
首先,在您的项目中,右键单击 "References" 和 select 添加引用。在"COM"菜单下,select"CertEnroll 1.0 Type Library".
功能的核心是 CX509CertificateRequestCmc
界面。 C# 中的 COM 接口有点特殊,你可以 "new" 它们,所以这是完全有效的:
var req = new CX509CertificateRequestCmc();
因此,要将您的 INF 转换为 CertEnroll,我认为它看起来类似于:
var req = new CX509CertificateRequestPkcs10();
req.Initialize(X509CertificateEnrollmentContext.ContextUser);
//Set basic constraints
var basicConstraints = new CX509ExtensionBasicConstraints();
basicConstraints.InitializeEncode(false, 0);
req.X509Extensions.Add((CX509Extension)basicConstraints);
//Set the hash algorithm
var hashAlgorithm = new CObjectId();
hashAlgorithm.InitializeFromAlgorithmName(ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID, 0, 0, "sha256");
req.HashAlgorithm = hashAlgorithm;
//Set the enhanced key usage
var eku = new CX509ExtensionEnhancedKeyUsage();
var serverAuth = new CObjectId();
serverAuth.InitializeFromValue("1.3.6.1.5.5.7.3.1");
var oids = new CObjectIds();
oids.Add(serverAuth);
eku.InitializeEncode(oids);
eku.Critical = false;
var privateKey = req.PrivateKey;
//Allow export as the INF does
privateKey.ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_FLAG;
privateKey.Length = 2048;
//Set the algorithm explicitly
var rsa = new CObjectId();
rsa.InitializeFromAlgorithmName(ObjectIdGroupId.XCN_CRYPT_ANY_GROUP_ID, 0, 0, "RSA");
privateKey.Algorithm = rsa;
privateKey.ProviderName = "Microsoft RSA SChannel Cryptographic Provider";
privateKey.ProviderType = X509ProviderType.XCN_PROV_RSA_SCHANNEL; //12
privateKey.KeyUsage = (X509PrivateKeyUsageFlags)0xA0;
privateKey.Existing = false;
privateKey.KeyProtection = X509PrivateKeyProtection.XCN_NCRYPT_UI_NO_PROTECTION_FLAG;
privateKey.MachineContext = true;
var dn = new CX500DistinguishedName();
dn.Encode("CN=subject", X500NameFlags.XCN_CERT_NAME_STR_NONE);
req.Subject = dn;
var cmc = new CX509CertificateRequestCmc();
cmc.InitializeFromInnerRequest(req);
cmc.ArchivePrivateKey = false;
cmc.Encode();
var data = cmc.RawData[EncodingType.XCN_CRYPT_STRING_BASE64REQUESTHEADER];
Console.WriteLine(data);
末尾的 "data" 变量包含请求,所有请求都没有保存到磁盘。
这里很可能缺少某些东西,但它确实会生成证书请求。我会咨询 CertEnroll documentation 以了解需要进行的任何进一步调整。