BouncyCastle 私钥转 X509Certificate2 私钥 (ECC)

BouncyCastle PrivateKey To X509Certificate2 PrivateKey (ECC)

使用 .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()?

谢谢!

更新:

这个post的原因是因为这个问题:

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.

来源显示,根据您所使用的平台,运行 会抛出异常。

                    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?");
  }
}