简体   繁体   English

BouncyCastle PrivateKey 到 X509Certificate2 PrivateKey (ECC)

[英]BouncyCastle PrivateKey To X509Certificate2 PrivateKey (ECC)

Using .NET Core 3.1 and BouncyCastle使用 .NET Core 3.1 和 BouncyCastle

I have a Private ECC key from Pkcs12.我有一个来自 Pkcs12 的私有 ECC 密钥。 How can I store this in X509Certificate2 Private Key please?请问如何将其存储在 X509Certificate2 私钥中? The reason I am trying it this way is because when I load the Pkcs12 as X509Certificate2, the X509Certificate2.PrivateKey method throws a "not implemented / algorithm not supported exception".我这样尝试的原因是,当我将 Pkcs12 加载为 X509Certificate2 时, X509Certificate2.PrivateKey方法会引发“未实现/算法不支持异常”。

This is what I have so far:这是我到目前为止所拥有的:

        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()?

Thank you!谢谢!

UPDATE:更新:

The reason for this post is due to this problem:这个帖子的原因是由于这个问题:

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.

The source shows that, depending on the platform you run on the exception is thrown.源代码显示,根据您运行的平台,抛出异常。

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

The private key is of type AsymmetricAlgorithm witch needs to be casted anyway to RSA or ECDsa.私钥是AsymmetricAlgorithm类型,无论如何都需要转换为 RSA 或 ECDsa。 I remember @bartonjs saying that one should use the GetXXXPrivateKey() methods.我记得@bartonjs 说应该使用GetXXXPrivateKey()方法。 So you can do that on your own:所以你可以自己做:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM