Is there any way to combine a certificate and a key (both received separately as Base64 strings from a service) into a .pfx file using C#/.NET Standard programmatically? Using a tool is not an option, since I need to automate it.
The context: I need to load a certificate and a private key (separate Base64 strings without headers and footers) to a X509Certificate2
object to pass it on to the app from a .NET Standard 1.6 library.
The problem is, there is no PrivateKey
property in the X509Certificate2
class in .NET Standard! So the only way for me to actually load the private key in a X509Certificate2
object is to combine it with the certificate itself in a .pfx file and load it like that in a constructor.
There's not a way to do this with framework types. It may be possible with BouncyCastle, or other libraries.
.NET Core 2.0 has added the ability to merge a certificate and a key object together (into a new X509Certificate2 object) via extension methods:
X509Certificate2 mergedCert = cert.CopyWithPrivateKey(rsaPrivateKey);
X509Certificate2 mergedCert = cert.CopyWithPrivateKey(dsaPrivateKey);
X509Certificate2 mergedCert = cert.CopyWithPrivateKey(ecdsaPrivateKey);
But that requires compiling specifically for netcoreapp20 (not netstandard20).
The framework types also don't have a way of loading key objects from binary representations (with the exception of CngKey.Import
, but that only works on Windows), only from the pre-parsed structures (RSAParameters
, DSAParameters
, ECParameters
).
The easiest way to accomplish this goal on Linux (if BouncyCastle can't help you out) is to use System.Process
to spawn a call similar to openssl pkcs12 -export -out tmp.pfx -in tmp.cer -inkey tmp.key -password pass:""
.
On Windows you could maybe use CngKey.Import and P/Invoke CertSetCertificateContextProperty (for CERT_NCRYPT_KEY_HANDLE_PROP_ID (78)) to then call cert.Export
on the mutated certificate.