Как исправить ошибку «CCertRequest :: Submit: сервер RPC недоступен. 0x800706ba»? - PullRequest
0 голосов
/ 04 февраля 2019

Сценарий:
Я изучаю AWS CloudHSM.До сих пор я

  • создал экземпляр EC2 с Центром обработки данных Windows Server 2019 , поскольку ОС
  • создала центр сертификации (корневой ЦС) на этом сервере с помощью DintinguisedИмя " CN = myservername-CA1 " (https://docs.aws.amazon.com/cloudhsm/latest/userguide/win-ca-setup.html)
  • при подключении к экземпляру EC2 через RDP я могу войти в свою облачную учетную запись hsm и управлять пользователями, создаватьновые ключи и т. д.

Сведения о CA:

  • Поставщик: RSA # Поставщик хранилища ключей Cavium
  • Длина ключа: 2048
  • Алгоритм хеширования: SHA256
  • Отличительное имя: CN = myservername-CA1
  • Журнал базы данных сертификатов: C: \ Windows \ system32 \ CertLog

Теперь я разработалпример приложения .Net WebAPI, которое должно отправить запрос CSR моему CA, и CA должен вернуть подписанный сертификат запрашивающей стороне.Это приложение размещается как веб-приложение на IIS в том же экземпляре EC2.

Исходный код (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 Key Storage Provider "или" RSA # Cavium Key Storage Provide r "используется для инициализации objCSP," Указан неверный поставщик. (Исключение из HRESULT: 0x80090013)"выдается исключение

  • , когда для инициализации objCSP используется " Microsoft Enhanced Cryptographic Provider v1.0 ", " CCertRequest :: Submit: сервер RPC недоступен. 0x800706ba «выброшено исключение»

Чтобы устранить проблему «Сервер RPC недоступен», я выполнил шаги https://itworldjd.wordpress.com/2015/10/21/pki-certificates-troubleshooting-certificate-enrollment-rpc-server-is-unavailable/, но не повезло.

...