在 .NET 中加载 ECC 私钥

Loading an ECC private key in .NET

我有一个 ECC 私钥和一个包含 public 密钥的证书文件。我可以获得 PEM 或 DER 格式的它们。

我可以使用以下代码将证书读入 X509Certificate

var certbytes = File.ReadAllBytes("certificate.pem");
var cert = new X509Certificate2(certbytes);

但是我无法加载私钥。我试过这段代码:

var keyContent = File.ReadAllBytes("certificate_private_key.pem");
var key = CngKey.Import(keyContent, CngKeyBlobFormat.EccPrivateBlob);

它抛出 Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException: 'An error occurred during encode or decode operation'

我还尝试了 CngKeyBlobFormat 参数的其他值。 Import 方法也对这些失败。

openssl 可以读取文件,并输出以下信息:

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-----

.NET 或 .NET Core 中是否有内置的 API 可以做到这一点?或者是否有第 3 方库可以做到这一点,如何做到?

.NET Core 3.0(目前处于预览状态)具有 ECDsa.ImportECPrivateKeyAsymmetricAlgorithm.ImportPkcs8PrivateKeyAsymmetricAlgorithm.ImportEncryptedPkcs8PrivateKey(并且 RSA 具有 RSAPublicKey 和 RSAPrivateKey)并且对于当前文件 (BEGIN EC PRIVATE KEY) 你想要第一个。

  • 这些方法的好消息是:它们存在。
  • 坏消息是:它们是下一版本的一部分,而不是当前版本。
  • 好:下个版本应该很快就是当前版本了。
  • 不好:他们只理解 BER/DER 数据,不理解 PEM。

最后一点意味着您当前必须找到 -----BEGIN EC PRIVATE KEY-----\n\n-----END EC PRIVATE KEY----- 之间的 base64 内容并 de-base64-it,然后将其传递到方法中。


据我所知,CNG 导入支持的唯一私钥格式是 PKCS8、加密的 PKCS8 和 CNG 私有格式。要使用 CngKey.Import,您首先需要将密钥文件转换为 PKCS#8,然后按照评论中的建议指定格式为 Pkcs8PrivateBlob