I have an ECC private and a certificate file which includes the public key. I can get them in either PEM or DER formats.
I can read the certificate into an X509Certificate
with this code:
var certbytes = File.ReadAllBytes("certificate.pem");
var cert = new X509Certificate2(certbytes);
But I'm unable to load the private key. I've tried this code:
var keyContent = File.ReadAllBytes("certificate_private_key.pem");
var key = CngKey.Import(keyContent, CngKeyBlobFormat.EccPrivateBlob);
It throws Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException: 'An error occurred during encode or decode operation'
.
I've also tried other values of the CngKeyBlobFormat
parameter. The Import method fails with those as well.
openssl can read the file, and it outputs the following information about it:
openssl ec -in certificate_private_key.pem -text
read EC key
Private-Key: (256 bit)
priv:
44:<cut>:68
pub:
04:<cut>:13
ASN1 OID: prime256v1
NIST CURVE: P-256
writing EC key
-----BEGIN EC PRIVATE KEY-----
MHcC <cut here>
-----END EC PRIVATE KEY-----
Is there built-in API in .NET or .NET Core which can do this? Or are there 3rd party libraries that can do it, and how?
.NET Core 3.0 (currently in preview) has ECDsa.ImportECPrivateKey
, AsymmetricAlgorithm.ImportPkcs8PrivateKey
, and AsymmetricAlgorithm.ImportEncryptedPkcs8PrivateKey
, (and RSA has RSAPublicKey and RSAPrivateKey) and for the current file (BEGIN EC PRIVATE KEY
) you'd want the first one.
The last point means that you currently would have to find the base64 content between the -----BEGIN EC PRIVATE KEY-----\n
and \n-----END EC PRIVATE KEY-----
and de-base64-it, then pass that into the methods.
The only private key formats that I know that are supported by CNG import are PKCS8, encrypted PKCS8, and CNG private formats. To use CngKey.Import you'd first need to convert the keyfile to PKCS#8 then specify that the format is Pkcs8PrivateBlob
, as suggested in the comments.