Anonymous
Как исправить ошибку «CCertRequest::Submit: сервер RPC недоступен. 0x800706ba»?
Сообщение
Anonymous » 06 мар 2026, 17:03
Сценарий:
Я изучаю AWS CloudHSM. На данный момент я
создал экземпляр EC2 с Windows Server 2019 Datacenter в качестве ОС
создал центр сертификации (корневой центр сертификации) на этом сервере с различающимся именем «CN=myservername-CA1 » (https://docs.aws.amazon.com/cloudhsm/la ... setup.html )
при подключении к экземпляру EC2 через RDP я могу войти в свою учетную запись Cloud HSM и управлять пользователями, создавать новые ключи и т. д.
Подробности CA:
Поставщик: Поставщик хранилища ключей RSA#Cavium
Длина ключа: 2048
Алгоритм хеширования: SHA256
Отличительное имя: CN=myservername-CA1
Журнал базы данных сертификатов: C:\Windows\system32\CertLog
Теперь я разработал образец приложения .Net WebAPI, которое должно отправлять запрос CSR в мой центр сертификации, а центр сертификации должен возвращать подписанный сертификат запрашивающей стороне. Это приложение размещается как веб-приложение в IIS на том же экземпляре EC2.
Исходный код (
https://blogs.msdn.microsoft.com/alejac ... and-net-c/ ):
Код: Выделить всё
using CloudHsmDemo.Models;
using System;
using System.Threading.Tasks;
using CERTENROLLLib;
using CERTCLILib;
namespace CloudHsmDemo.Services
{
public interface ICertificateService
{
Task 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 SignAsync(CertificateSigningRequest csr)
{
if (csr.ShouldReturnDummyData)
{
return await DummySigningAsync(csr);
}
else
{
return await ActualSigningAsync(csr);
}
}
private async Task DummySigningAsync(CertificateSigningRequest csr)
{
return PopulateCertificateSigningResponse("Sample Certificate", "Sample Message");
}
private async Task 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,
"\\"
);
// 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 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=-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
}
Проблемы:
когда для инициализации objCSP используется «Поставщик ключей Cavium Key Storage » или «RSA#Cavium Key Storage
Provide r», «Неверный поставщик
». (Исключение из HRESULT: 0x80090013)" выдается
когда "Microsoft Enhanced Cryptographic Provider v1.0 " используется для инициализации objCSP, выдается исключение "CCertRequest::Submit: Сервер RPC
недоступен 0x800706ba"
Чтобы решить проблему «Сервер RPC недоступен», я выполнил шаги
https://itworldjd.wordpress.com/2015/10 ... available/ , но безуспешно.
Подробнее здесь:
https://stackoverflow.com/questions/545 ... 0706ba-err
1772805820
Anonymous
[b]Сценарий:[/b] Я изучаю AWS CloudHSM. На данный момент я [list] [*]создал экземпляр EC2 с [b]Windows Server 2019 Datacenter[/b] в качестве ОС [*]создал центр сертификации (корневой центр сертификации) на этом сервере с различающимся именем «[b]CN=myservername-CA1[/b]» (https://docs.aws.amazon.com/cloudhsm/latest/userguide/win-ca-setup.html) [*]при подключении к экземпляру EC2 через RDP я могу войти в свою учетную запись Cloud HSM и управлять пользователями, создавать новые ключи и т. д. [/list] Подробности CA: [list] [*]Поставщик: Поставщик хранилища ключей RSA#Cavium [*]Длина ключа: 2048 [*]Алгоритм хеширования: SHA256 [*]Отличительное имя: CN=myservername-CA1 [*]Журнал базы данных сертификатов: C:\Windows\system32\CertLog [/list] Теперь я разработал образец приложения .Net WebAPI, которое должно отправлять запрос CSR в мой центр сертификации, а центр сертификации должен возвращать подписанный сертификат запрашивающей стороне. Это приложение размещается как веб-приложение в IIS на том же экземпляре EC2. [b]Исходный код[/b] (https://blogs.msdn.microsoft.com/alejacma/2008/09/05/how-to-create-a-certificate-request-with-certenroll-and-net-c/): [code]using CloudHsmDemo.Models; using System; using System.Threading.Tasks; using CERTENROLLLib; using CERTCLILib; namespace CloudHsmDemo.Services { public interface ICertificateService { Task 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 SignAsync(CertificateSigningRequest csr) { if (csr.ShouldReturnDummyData) { return await DummySigningAsync(csr); } else { return await ActualSigningAsync(csr); } } private async Task DummySigningAsync(CertificateSigningRequest csr) { return PopulateCertificateSigningResponse("Sample Certificate", "Sample Message"); } private async Task 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, "\\" ); // 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 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=-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; } } } [/code] [b]Мой пример запроса JSON:[/b] [code]{ "CommonName":"My Test CSR", "Organization":"My Office", "OrganizationalUnit":"My Department", "CityOrLocality":"Sydney", "StateOrProvince":"NSW", "CountryOrRegion":"AU", "KeySize":2048, "ShouldReturnDummyData": false } [/code] [b]Проблемы:[/b] [list] [*]когда для инициализации objCSP используется «[b]Поставщик ключей Cavium Key Storage[/b]» или «[b]RSA#Cavium Key Storage Provide[/b]r», «Неверный поставщик ». (Исключение из HRESULT: 0x80090013)" выдается [*]когда "[b]Microsoft Enhanced Cryptographic Provider v1.0[/b]" используется для инициализации objCSP, выдается исключение "CCertRequest::Submit: Сервер RPC недоступен 0x800706ba" [/list] Чтобы решить проблему «Сервер RPC недоступен», я выполнил шаги https://itworldjd.wordpress.com/2015/10/21/pki-certificates-troubleshooting-certificate-enrollment-rpc-server-is-unavailable/, но безуспешно. Подробнее здесь: [url]https://stackoverflow.com/questions/54509185/how-to-fix-ccertrequestsubmit-the-rpc-server-is-unavailable-0x800706ba-err[/url]