首页 > 解决方案 > 如何向 Windows CA 提交 CSR 以从 C# 进行签名?

问题描述

我的场景:

我有一个运行Windows Server 2016 DataCenter OS的 EC2 实例。此 EC2 实例配置为用作CAIIS服务器(我正在测试cloudhsm,因此我可以在同一服务器中拥有多个服务)。我的 CA 配置了RSA#Cavium 密钥存储提供程序(因为它支持 AWS CloudHSM 密钥存储提供程序)。现在,从我的示例 .Net WebAPI 应用程序中,我可以使用以下代码创建 CSR:

private async Task<CertificateSigningResponse> ActualSigningAsync(CertificateSigningRequest csr)
        {
            CertificateSigningResponse certificateSigningResponse;
            try
            {
                using (RSA rsa = RSA.Create(csr.KeySize))
                {
                    CertificateRequest request = new CertificateRequest("CN=servername-CA2", rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);

                    OidCollection oidCollection = new OidCollection();
                    oidCollection.Add(new Oid("1.3.6.1.5.5.7.3.8"));

                    request.CertificateExtensions.Add(new X509BasicConstraintsExtension(true, false, 0, true));
                    request.CertificateExtensions.Add(new X509EnhancedKeyUsageExtension(oidCollection, true));
                    request.CertificateExtensions.Add(new X509SubjectKeyIdentifierExtension(request.PublicKey, false));

                    var serialNumberInBytes = System.Text.Encoding.UTF8.GetBytes(Guid.NewGuid().ToString());

                    /*
                    // below line creates a self signed certificate
                    var selfSignedCertificate = request.Create(
                        new X500DistinguishedName("CN=servername-CA2"),
                        X509SignatureGenerator.CreateForRSA(rsa, RSASignaturePadding.Pkcs1),
                        DateTimeOffset.Now,
                        DateTimeOffset.Now.AddMonths(1),
                        serialNumberInBytes);
                    */

                    var certSigningRequest = request.CreateSigningRequest(X509SignatureGenerator.CreateForRSA(rsa, RSASignaturePadding.Pkcs1));

                    if (certSigningRequest != null)
                    {
                        certificateSigningResponse = PopulateCertificateSigningResponse(JsonConvert.SerializeObject(certSigningRequest), $"Sample Cert with Sl#: {certSigningRequest}");
                    }
                    else
                    {
                        certificateSigningResponse = PopulateCertificateSigningResponse("", $"Error: {request.PublicKey}");
                    }
                }
            }
            catch (Exception ex)
            {
                certificateSigningResponse = PopulateCertificateSigningResponse(string.Empty, ex.Message);
            }

            return certificateSigningResponse;

        } 

现在,我想将此 CSR 发送到我的 CA(在 EC2 上运行)并对其进行签名。签名后,我想将签名的证书发回给用户。目前,我已经在同一个 EC2 实例上托管了我的示例 webapi 应用程序。这个应用程序实际上公开了一个端点,我可以通过邮递员点击它并将一些数据作为请求正文 (POST) 传递。

因此,理想情况下,应用程序接收我的 POST 请求并从中提取数据,然后使用该数据创建一个 csr。现在我想将此 csr 发送给我的 CA,对其进行签名,最后将签名证书返回给用户。下面的伪代码可能会让您对我的要求有所了解:

//pseudo code; not existed
// request is generated in above code
var caService = new CAService();//can use my ca info i.e. name, public dns, ip
var response = await caService.SignAsync(request);//response should be a cert
return response;

我见过很少使用CertUtilLib/CertEnrollLib的帖子,但我想通过完全托管的代码来实现这一点。另外,如果不可能,请建议我一些替代方案。谢谢。

编辑 1(在 Michal 评论之后)

以下是一些您感兴趣的信息:

当前场景:

我的意图:

标签: c#amazon-ec2cahsm.net-4.7.2

解决方案


推荐阅读