如何解决“ CCertRequest :: Submit:RPC服务器不可用。0x800706ba”错误?

时间:2019-02-04 01:19:32

标签: c# amazon-web-services amazon-ec2 cryptography hsm

场景:
我正在学习AWS CloudHSM。到目前为止,我已经

  • 使用 Windows Server 2019数据中心作为操作系统
  • 创建了一个EC2实例
  • 在该服务器上创建了具有权威名称“ CN = myservername-CA1 ”(https://docs.aws.amazon.com/cloudhsm/latest/userguide/win-ca-setup.html)的证书颁发机构(根CA)
  • 通过RDP连接到EC2实例时,我可以登录到我的云hsm帐户并可以管理用户,创建新密钥等。

CA的详细信息:

  • 提供者:RSA#Cavium密钥存储提供者
  • 密钥长度:2048
  • 哈希算法:SHA256
  • 专有名称:CN = myservername-CA1
  • 证书数据库日志:C:\ Windows \ system32 \ CertLog

现在,我已经开发了一个示例.Net WebAPI应用程序,该应用程序应该将CSR请求发送到我的CA,并且CA应该将签名证书返回给请求者。该应用程序作为Web应用程序托管在同一EC2实例上的IIS上。

源代码https://blogs.msdn.microsoft.com/alejacma/2008/09/05/how-to-create-a-certificate-request-with-certenroll-and-net-c/):

using CloudHsmDemo.Models;
using System;
using System.Threading.Tasks;
using CERTENROLLLib;
using CERTCLILib;

namespace CloudHsmDemo.Services
{
    public interface ICertificateService
    {
        Task<CertificateSigningResponse> SignAsync(CertificateSigningRequest csr);
    }

    public class CertificateService : ICertificateService
    {
        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;

        public async Task<CertificateSigningResponse> SignAsync(CertificateSigningRequest csr)
        {
            if (csr.ShouldReturnDummyData)
            {
                return await DummySigningAsync(csr);
            }
            else
            {
                return await ActualSigningAsync(csr);
            }
        }

        private async Task<CertificateSigningResponse> DummySigningAsync(CertificateSigningRequest csr)
        {
            return PopulateCertificateSigningResponse("Sample Certificate", "Sample Message");
        }

        private async Task<CertificateSigningResponse> ActualSigningAsync(CertificateSigningRequest csr)
        {
            //  Create all the objects that will be required

            CCertConfig objCertConfig = new CCertConfigClass();

            CCertRequest objCertRequest = new CCertRequestClass();

            // string strCAConfig;

            string strRequest;

            int iDisposition;

            string strDisposition;

            string strCert;

            CertificateSigningResponse certificateSigningResponse;

            try

            {

                strRequest = await CreateCertificateSigningRequest(csr);


                // Get CA config from UI

                // strCAConfig = objCertConfig.GetConfig(CC_DEFAULTCONFIG);

                //strCAConfig = objCertConfig.GetConfig(CC_UIPICKCONFIG);


                // Submit the request

                iDisposition = objCertRequest.Submit(

                    CR_IN_BASE64 | CR_IN_FORMATANY,

                    strRequest,

                    null,

                    "<my_ec2_instance_public_dns>\\<my_server_name>"

                );

                // Check the submission status

                if (CR_DISP_ISSUED != iDisposition) // Not enrolled

                {

                    strDisposition = objCertRequest.GetDispositionMessage();


                    if (CR_DISP_UNDER_SUBMISSION == iDisposition) // Pending
                    {
                        certificateSigningResponse = PopulateCertificateSigningResponse(string.Empty, $"The submission is pending: {strDisposition}");
                    }

                    else // Failed

                    {
                        certificateSigningResponse = PopulateCertificateSigningResponse(string.Empty, $"The submission failed: {strDisposition}; Last Status: {objCertRequest.GetLastStatus().ToString()}");
                    }

                }


                // Get the certificate

                strCert = objCertRequest.GetCertificate(

                    CR_OUT_BASE64 | CR_OUT_CHAIN

                );


                certificateSigningResponse = PopulateCertificateSigningResponse(strCert, "Certificate signing process succeeded.");

            }

            catch (Exception ex)

            {

                certificateSigningResponse = PopulateCertificateSigningResponse(string.Empty, ex.Message);

            }
            if (certificateSigningResponse == null)
            {
                certificateSigningResponse = PopulateCertificateSigningResponse(string.Empty, "Certificate signing process failed.");
            }
            return certificateSigningResponse;
        }

        // this method creates a request string properly when 
        private async Task<string> CreateCertificateSigningRequest(CertificateSigningRequest csr)
        {
            //  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 Enhanced Cryptographic Provider v1.0");


                //objCSP.InitializeFromName("Cavium Key Storage Provider");

                //  Add this CSP object to the CSP collection object

                objCSPs.Add(objCSP);


                //  Provide key container name, key length and key spec to the private key object

                objPrivateKey.Length = csr.KeySize;

                objPrivateKey.KeySpec = X509KeySpec.XCN_AT_SIGNATURE;

                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;


                //  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(

                    X509KeyUsageFlags.XCN_CERT_DIGITAL_SIGNATURE_KEY_USAGE |

                    X509KeyUsageFlags.XCN_CERT_NON_REPUDIATION_KEY_USAGE |

                    X509KeyUsageFlags.XCN_CERT_KEY_ENCIPHERMENT_KEY_USAGE |

                    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.2"); // 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=<myservername>-CA1", 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_BASE64

                );
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return strRequest;
        }

        private CertificateSigningResponse PopulateCertificateSigningResponse(string certificate, string message)
        {
            var responseObject = new CertificateSigningResponse
            {
                Certificate = certificate,
                Message = message,
                DateTimeInUTC = DateTime.UtcNow,
                Status = string.IsNullOrWhiteSpace(certificate) == true ? "Fail" : "Success"
            };
            return responseObject;
        }
    }
}

我的示例JSON请求:

{
    "CommonName":"My Test CSR",
    "Organization":"My Office",
    "OrganizationalUnit":"My Department",
    "CityOrLocality":"Sydney",
    "StateOrProvince":"NSW",
    "CountryOrRegion":"AU",
    "KeySize":2048,
    "ShouldReturnDummyData": false
}

问题:

  • Cavium密钥存储提供程序”或“ RSA#Cavium密钥存储”时 提供 r”用于初始化objCSP,“ 无效的提供者 指定。 (来自HRESULT的异常:0x80090013)”引发了异常

  • 当使用“ Microsoft增强加密提供程序v1.0 ”来初始化objCSP时,“ CCertRequest :: Submit:RPC服务器是 不可用。 0x800706ba ”引发了异常

要解决“ RPC服务器不可用”的问题,我已经按照步骤https://itworldjd.wordpress.com/2015/10/21/pki-certificates-troubleshooting-certificate-enrollment-rpc-server-is-unavailable/进行了操作,但是不走运。

1 个答案:

答案 0 :(得分:0)

我也遇到了这个错误。希望有人可以从我的解决方法中受益。

在通过网络注册请求新证书后,我也收到了错误消息。

CCertRequest :: Submit:RPC服务器不可用。 0x800706ba(WIN32:1722 RPC_S_SERVER_UNAVAILABLE)

在不涉及DCOM权限的所有细节的情况下,您需要确保您是远程访问证书Web服务器,而不是从CA服务器本地访问。