允许在C#中为CX509PrivateKeyClass提供密钥保护

问题描述 投票:2回答:1

我们目前有一种使用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。每次请求证书时,都会提示用户保护密钥

对于我的.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);

所以我的问题是如何向屏幕快照中所示的私钥添加密钥保护?

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

任何指导都会受到欢迎,很痛苦的是,我对CSR一代还很陌生。

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

非常感谢

我们目前有一种使用Microsoft Active Directory证书服务生成CA证书的解决方案。我们有一个您可以登录的应用程序,您可以发送CA的请求...

c# ssl bouncycastle ca certenroll
1个回答
0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.