gpt4 book ai didi

c# - 在 C# 中允许 CX509PrivateKeyClass 的 KeyProtection

转载 作者:行者123 更新时间:2023-12-04 22:37:55 25 4
gpt4 key购买 nike

我们目前有一个使用 Microsoft Active Directory 证书服务生成 CA 证书的解决方案。

我们有一个您可以登录的应用程序,您可以发送 CA 证书请求。

在幕后,这会加载一个 iframe(指向 MS CA 证书服务上的表单)使用 jQuery 复制数据负载并提交表单。

表单提交使用 ActiveX 和 CertEnroll 创建一个 CSR,并将其发布到另一个 ASP 页。 (整个MS AD证书服务都是ASP页面)

问题是这只适用于IE(显然)

我的建议是移动 CSR 生成服务器端,这样它就不会依赖于 IE 并且可以从任何浏览器中使用。

我有一个可行的解决方案,它将数据发送到 api,并在 api 中生成 CSR 并将其转发到 MS CA 证书服务器,这会生成有效的证书。

问题

问题是,一旦我安装了证书,就会丢失“您拥有与此证书对应的私钥”的信息。在现有系统上,此消息显示如下:

expected certificate

我的假设是这是因为尚未为私钥设置 KeyProtection。不幸的是,它在现有 VBScript 实现中使用的标志需要用户输入:XCN_NCRYPT_UI_PROTECT_KEY_FLAG。每次请求证书时,都会提示用户保护 key

对于我的 .Net Framework 实现,我尝试了两种不同的 CSR 生成器,一种使用 Bouncy CaSTLe,另一种使用 CERTENROLLLib 的互操作。

我将在下面显示的代码将是 CERTENROLLLib 实现,但如果有人对这两种解决方案有任何想法,我会很高兴听到他们

CERTENROLLLib CSR 一代

        var values = new Dictionary<string, string>
{
{ "E", emailAddress },
{ "CN", commonName },
{ "OU", organizationalUnit },
{ "L", locality }
};

var privateKey = new CX509PrivateKeyClass
{
Length = 1024,
MachineContext = false,
CspInformations = GetCryptographicProvider(),
// This can't be set as it requires UI feedback
//KeyProtection = X509PrivateKeyProtection.XCN_NCRYPT_UI_PROTECT_KEY_FLAG,
ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_NONE,
};


// Create the actual key pair
privateKey.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
var certificateRequest = new CX509CertificateRequestPkcs10Class();

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

var extension = new CX509ExtensionsClass
{
GetExtensionKeyUsage(),
GetExtensionEnhancedKeyUsage()
};

certificateRequest.X509Extensions.AddRange(extension);

// Encode the name in using the Distinguished Name object
var valueCollection = values.Select(v => $"{v.Key}={v.Value}").Reverse();

var subject = new CX500DistinguishedNameClass();
subject.Encode(
string.Join(";", valueCollection), X500NameFlags.XCN_CERT_NAME_STR_ENABLE_PUNYCODE_FLAG
);

// Assigning the subject name by using the Distinguished Name object initialized above
certificateRequest.Subject = subject;

// Create enrollment request
var enrollmentRequest = new CX509EnrollmentClass();
enrollmentRequest.InitializeFromRequest(certificateRequest);

var csr = enrollmentRequest.CreateRequest(EncodingType.XCN_CRYPT_STRING_BASE64REQUESTHEADER);

所以我的问题是如何为私钥添加 key 保护,如屏幕截图所示?

由于这是服务器端,我不能指望任何用户反馈,所以还有另一种方法。

任何指导都将受到欢迎,这可能很清楚,我对 CSR 的产生还是很陌生。

最终这将被重写,我们可能会生成我们自己的证书,但我只是试图改善目前的情况。

非常感谢

最佳答案

首先,这不是一个答案,而是分享一些可能有所帮助的想法和经验。

我之前在 CERTENROLLLib 库的 1.0.0.0 版本中使用了类似的代码(这是要走的路,因为它有大多数用于生成证书的设置,而不是 Bouncy CaSTLe)。

我认为您的请求是正确的,但不知何故,MS CA 正在颁发没有私钥的证书,因此您导入它并最终丢失“您有一个与此证书对应的私钥”。

我这样说是因为我的代码没有设置 KeyProtection并保留默认值 X509PrivateKeyProtection.XCN_NCRYPT_UI_NO_PROTECTION_FLAG ,但我能够生成包含私钥的证书(我实际上再次使用 CERTENROLLLib 来生成证书而不是 MS CA,所以这是一个主要区别)。

这就像以 .cer 格式(不带 PK)和 .pfx 格式(带 PK)导出证书。

因此,MS CA 的注册请求必须有一些特殊设置。

这是我的引用代码,它创建一个证书并将其添加到本地计算机上的个人证书中。

    // Create enrollment request
var enrollmentRequest = new CX509Enrollment();
enrollmentRequest.InitializeFromRequest(certificateRequest);

string csr = enrollmentRequest.CreateRequest();

// and install it back as the response
enrollmentRequest.InstallResponse(InstallResponseRestrictionFlags.AllowUntrustedCertificate,
csr, EncodingType.XCN_CRYPT_STRING_BASE64, ""); // no password
// output a base64 encoded PKCS#12 so we can import it back to the .Net security classes
var base64encoded = enrollmentRequest.CreatePFX("", // no password, this is for internal consumption
PFXExportOptions.PFXExportChainWithRoot);

// instantiate the target class with the PKCS#12 data (and the empty password)
var certificate = new System.Security.Cryptography.X509Certificates.X509Certificate2(
System.Convert.FromBase64String(base64encoded), "",
// mark the private key as exportable (this is usually what you want to do)
System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.Exportable
);

我也决定发这个,因为你说

we'll probably be generating our own certificates



这实际上是我的代码所做的,它包括 PK,所以也许这篇文章可能会有所帮助。

关于c# - 在 C# 中允许 CX509PrivateKeyClass 的 KeyProtection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62150258/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com