1

We have a self-signed CA certificate with private key stored in a HSM solution. We need to create a short-lived X.509 certificate signed by the CA certificate through .NET code. The short-lived X.509 certificate will be used for client certificate authentication against a REST-based service over TLS/HTTPS.

The HSM solution is using Key Storage Provider (KSP) integration with Microsoft Certificate Store, so the Crypto Next Generation (CNG) libraries must be used to get the private key.

Through X509CertificateExtensions.GetCngPrivateKey() we're able to get access a CngKey object that represents the private key.

However, we're not able to use the CngKey together with BouncyCastle

AsymmetricCipherKeyPair issuerKeyPair=null;
if (issuerCertificate.HasCngKey())
{
   var cngPrivateKey = issuerCertificate.GetCngPrivateKey();
   var rsa = new RSACng(cngPrivateKey);

   issuerKeyPair = DotNetUtilities.GetRsaKeyPair(privateKey);
}

Fails with the following exception thrown

System.Security.Cryptography.CryptographicException: Invalid type specified.

   at System.Security.Cryptography.NCryptNative.ExportKey(SafeNCryptKeyHandle key, String format)
   at System.Security.Cryptography.CngKey.Export(CngKeyBlobFormat format)
   at System.Security.Cryptography.RSACng.ExportParameters(Boolean includePrivateParameters)

Edit: Think the reason this fails, is that DotNetUtilities.GetRsaKeyPair tries to Export the private key through rsa.ExportParameters(true). This is not allowed by the HSM and it throws an exception. Seems like a need a different way to reference the private key

Edit #2: Raised feature request to Bouncy Castle and there is a response on how this could be implemented as part of the framework.

dparnas
  • 4,090
  • 4
  • 33
  • 52
  • It would be better if we would know how do you plan to use the key (for what applications or tasks). I'm not familiar with BouncyCastle, but there should be API that would accept a `HCRYPTKEY` handle. – Crypt32 Jan 24 '17 at 10:39
  • Added " The short-lived X.509 certificate will be used for client certificate authentication against a REST-based service over TLS/HTTPS." – dparnas Jan 24 '17 at 12:09
  • To clarify: how exactly you want to use the key? To sign this short-lived certificate? In this case I would suggest to use CA service to sign short-lived certificate. In this case, CA will take care about everything. What you only need is to prepare CSR from client. – Crypt32 Jan 24 '17 at 12:14
  • 1
    We have a self-signed CA certificate (not a CA service) which has the private key in HSM. This self-signed CA certificate is trusted by a REST-based service over TLS/HTTPS. Our application receives a TLS/HTTPS request with kerberos authentication, and will based on this act as a proxy for the request to REST-based service .Since the REST-based service only supports X.509 client certificates, we generate on-the-fly an X.509 certificate signed with the private key of the CA certificate. – dparnas Jan 24 '17 at 13:10
  • Ok, I got your final goal. But...not a CA service? According to your post: `The HSM solution is using Key Storage Provider (KSP) integration with Microsoft Certificate Services`. In the case if you don't have it, you should use CA service (ADCS or whatever you prefer) to perform certificate signing operations. Do not reinvent the wheel. – Crypt32 Jan 24 '17 at 13:16
  • sorry, I was wrong in that certificate services was used. It only uses the standard windows certificate store. ADCS could be a viable path, but then we need to sign the request with a key stored in HSM to achieve the security we want (as far as I understand) – dparnas Jan 24 '17 at 13:27
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/133893/discussion-between-crypt32-and-dparnas). – Crypt32 Jan 24 '17 at 13:28

0 Answers0