【问题标题】:Loading an ECC private key in .NET在 .NET 中加载 ECC 私钥
【发布时间】:2019-10-02 07:33:33
【问题描述】:

我有一个 ECC 私有和一个包含公钥的证书文件。我可以以 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 可以做到这一点?或者是否有第三方库可以做到这一点,以及如何做到这一点?

【问题讨论】:

  • 感谢您的提示。 openssl pkcs8 看不懂文件,只能openssl ec。我已经拥有 DER 和 PEM 格式的文件,但都不起作用。根据CngKeyBlobFormat 参数,异常是An error occurred during encode or decode operationThe parameter is incorrect。我也试过用openssl ec -in certificate_private_key.der -inform DER -param_enc explicit -out explicit.der -outform der将DER文件转换为显式EC文件,并使用CngKeyBlobFormat.EccFullPrivateBlob作为格式,但导入时仍然失败。
  • 啊,在那种情况下它是 X9.62 格式。真的应该从-----BEGIN EC PRIVATE KEY----- 标头中看到这一点。 X9.62 私钥是 PKCS#8 文件中的内容。
  • 试试openssl pkcs8 -topk8 -nocrypt -in oldfile.pem -out newfile.pem - 我猜-outform DER 可能也可以。
  • 运气好吗?首先转换为二进制 PKCS#8 格式,然后使用Pkcs8PrivateBlob 应该真的可以工作。
  • 是的,这行得通。 (抱歉回复晚了——其他工作和睡眠妨碍了)。现在可以使用var privatekey = File.ReadAllBytes("newfile.der"); var privkey = CngKey.Import(privatekey, CngKeyBlobFormat.Pkcs8PrivateBlob); var privkeyecdsa = new ECDsaCng(privkey); 读取 DER 文件

标签: c# cryptography x509certificate2


【解决方案1】:

.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----- 和 de-base64-it 之间找到 base64 内容,然后将其传递给方法。


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

【讨论】:

  • .NET 中是否有任何 PEM 解码实用程序,或者您是否必须使用例如有弹性吗?
  • @MaartenBodewes 目前没有。手卷或类似 BouncyCastle 的 PEMParser 是目前要走的路。也许下一个版本我可以得到一个符合 RFC 7468 的版本(例如,忽略 RFC 1421 中的标头部分)。
  • 谢谢@bartonjs,这行得通。使用问题中描述的原始文件的 DER 编码版本,我可以做到 var ecdsa = ECDsa.Create(); ecdsa.ImportECPrivateKey(privatekey, out _); ecdsa.VerifyHash(dataToVerify, signature); 我很确定 .NET Core 3.0 会在需要投入生产之前推出,所以我想我会去的沿着这条路走下去。
猜你喜欢
  • 2016-09-25
  • 2016-09-20
  • 1970-01-01
  • 1970-01-01
  • 2017-03-12
  • 2015-02-24
  • 2019-07-12
  • 1970-01-01
  • 2011-08-14
相关资源
最近更新 更多