【问题标题】:BouncyCastle PrivateKey To X509Certificate2 PrivateKey (ECC)BouncyCastle PrivateKey 到 X509Certificate2 PrivateKey (ECC)
【发布时间】:2021-03-09 06:07:19
【问题描述】:

使用 .NET Core 3.1 和 BouncyCastle

我有一个来自 Pkcs12 的私有 ECC 密钥。请问如何将其存储在 X509Certificate2 私钥中? 我之所以这样尝试,是因为当我将 Pkcs12 加载为 X509Certificate2 时,X509Certificate2.PrivateKey 方法会抛出“未实现/算法不支持异常”。

这是我目前所拥有的:

        using var stream = new MemoryStream(myPkcs12);

        Pkcs12Store pstore = new Pkcs12Store(stream, password.ToCharArray());
        
        var name = "";
        foreach (string alias in store.Aliases)
        {
            if (pstore.IsKeyEntry(alias))
            {
                name = alias;
            }
        }

        var key = pstore.GetKey(name);

            var cert = new X509Certificate2(myPkcs12, "mypassword", X509KeyStorageFlags.EphemeralKeySet | X509KeyStorageFlags.Exportable);
          
                cert.PrivateKey = // key? I imagine it is incorrect to use  DotNetUtilities.ToRSA()?

谢谢!

更新:

发这个帖子的原因是因为这个问题:

private const string EccTestCert = "MIINbQIBAzCCDSkGCSqGSIb3DQEHAaCCDRoEgg0WMIIN.... 9wQUpQgYbgB7yknIW7Oaz3hogAVihJoCAgfQ";
var cert = new X509Certificate2(Convert.FromBase64String(EccTestCert), "1");

//  If you inspect it, the PrivateKey throws an exception.  Whilst with an RSA cert, it will not.

【问题讨论】:

  • PKCS#12 包含证书和私钥。因此,当使用 new X509Certificate2(myPkcs12...) 导入 pkcs12 时,该实例是带有私钥的证书 - 因此您可以使用它进行签名或解密。
  • @DanielFisherlennybacon 嗨,当我尝试使用 ECC 证书进行此操作时,X509Certificate 无法返回 PrivateKey 供我使用。我将更新一个示例 Pkcs12。

标签: c# .net cryptography certificate bouncycastle


【解决方案1】:

源码显示,根据你运行的平​​台,会抛出异常。

                    switch (GetKeyAlgorithm())
                    {
                        case Oids.Rsa:
                            _lazyPrivateKey = Pal.GetRSAPrivateKey();
                            break;
                        case Oids.Dsa:
                            _lazyPrivateKey = Pal.GetDSAPrivateKey();
                            break;
                        default:
                            // This includes ECDSA, because an Oids.EcPublicKey key can be
                            // many different algorithm kinds, not necessarily with mutual exclusion.
                            //
                            // Plus, .NET Framework only supports RSA and DSA in this property.
                            throw new NotSupportedException(SR.NotSupported_KeyAlgorithm);
                    }

私钥是AsymmetricAlgorithm 类型,无论如何都需要转换为 RSA 或 ECDsa。我记得@bartonjs 说应该使用GetXXXPrivateKey() 方法。所以你可以自己做:

string EccTestCert = "{base64-pkcs-12-here}";
var cert = new X509Certificate2(Convert.FromBase64String(EccTestCert), "1");

if (cert.HasPrivateKey) {
  var key =
    (AsymmetricAlgorithm) cert.GetRSAPrivateKey()
      ?? cert.GetECDsaPrivateKey()
        ?? throw new NotSupportedException("Who still uses DSA?");

  if (key is ECDsa ecdsa) {
    var ecdsaSignature = ecdsa.SignData(new byte[]{ 0x00}, HashAlgorithmName.SHA256);
  } else if (key is RSA rsa) {
    var rsaSignature = rsa.SignData(new byte[]{ 0x00}, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
  } else {
    throw new NotSupportedException("Who still uses DSA?");
  }
}

【讨论】:

  • @PKCS12 如果你投了赞成票,它回答了你的问题,你能接受它吗?
  • 谢谢。你介意删除或加扰 Pkcs12 吗?
  • 欢迎。数据替换为占位符。
  • " 我记得@bartonjs 说应该使用 GetXXXPrivateKey() 方法。"是的,我终于和人们打成一片了!
  • 到目前为止,我们的道路不止一次交叉 :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-29
  • 1970-01-01
  • 1970-01-01
  • 2017-05-19
  • 2018-06-11
相关资源
最近更新 更多