在 .NET 中加载 ECC 私钥

Ras*_*usW 4 c# cryptography x509certificate2

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

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

var certbytes = File.ReadAllBytes("certificate.pem");
var cert = new X509Certificate2(certbytes);
Run Code Online (Sandbox Code Playgroud)

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

var keyContent = File.ReadAllBytes("certificate_private_key.pem");
var key = CngKey.Import(keyContent, CngKeyBlobFormat.EccPrivateBlob);
Run Code Online (Sandbox Code Playgroud)

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

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

openssl 可以读取该文件,并输出有关它的以下信息:

var certbytes = File.ReadAllBytes("certificate.pem");
var cert = new X509Certificate2(certbytes);
Run Code Online (Sandbox Code Playgroud)

.NET 或 .NET Core 中是否有可以执行此操作的内置 API?或者是否有可以做到这一点的 3rd 方图书馆,以及如何做到这一点?

bar*_*njs 6

.NET Core 3.0(目前为预览版)有ECDsa.ImportECPrivateKeyAsymmetricAlgorithm.ImportPkcs8PrivateKey、 和AsymmetricAlgorithm.ImportEncryptedPkcs8PrivateKey,(RSA 有 RSAPublicKey 和 RSAPrivateKey),对于当前文件 ( BEGIN EC PRIVATE KEY),您需要第一个。

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

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


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

  • 谢谢@bartonjs,这有效。使用问题中描述的原始文件的 DER 编码版本,我可以执行 `var ecdsa = ECDsa.Create(); ecdsa.ImportECPrivateKey(privatekey, out _); ecdsa.VerifyHash(dataToVerify, signature);` 我很确定 .NET Core 3.0 会在需要投入生产之前推出,所以我想我会走这条路。 (2认同)