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.