如何修复"CCertRequest::Submit: The RPC server is unavailable. 0x800706ba"错误?



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

  • 使用Windows Server 2019 Datacenter作为操作系统创建了一个EC2实例
  • 在此服务器上创建了一个证书颁发机构(根CA),Dintinguised Name为">CN=myservername-CA1"(https://docs.aws.amazon.com/cloudhsm/latest/userguide/win-ca-setup.html)
  • 当通过RDP连接到EC2实例时,我可以登录到我的云hsm帐户,并可以管理用户、创建新密钥等

CA的详细信息:

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

现在,我开发了一个示例.Net WebAPI应用程序,该应用程序应该向我的CA发送CSR请求,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 Key Storage Provider"或">RSA#Cavium密钥存储Provider"用于初始化objCSP,">无效提供程序指定。(HRESULT:0x80090013中的异常)"引发异常

  • 当">Microsoft Enhanced Cryptographic Provider v1.0"用于初始化objCSP时,">CCertRequest::Submit:RPC服务器不可用的0x800706ba"引发异常

为了解决"RPC服务器不可用"的问题,我按照以下步骤进行了操作https://itworldjd.wordpress.com/2015/10/21/pki-certificates-troubleshooting-certificate-enrollment-rpc-server-is-unavailable/但没有运气。

我也遇到了这个错误。希望有人能从我的处理方式中受益。

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

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

在不深入了解DCOM权限的所有细节的情况下,您需要确保您正在远程访问证书web服务器,而不是从CA服务器本地访问。

相关内容

  • 没有找到相关文章

最新更新