简体   繁体   English

从Bouncy Castle C中的私钥获取公钥#

[英]Get public key from private key in Bouncy Castle C#

So I have an encrypted private key PEM. 所以我有一个加密的私钥PEM。 I can read it and get the private key with the following: 我可以阅读它并获得以下私钥:

AsymmetricKeyParameter key;
using (var sr = new StringReader(pem))
using (var pf = new PassowrdFinder { Password = password })
{
  var reader = new PemReader(sr, pf);
  key = (AsymmetricKeyParameter)reader.ReadObject();
}

I also need the public key, to create the SPKI later on. 我还需要公钥,以便稍后创建SPKI。 I tried 我试过了

var keyPair = new AsymmetricCipherKeyPair(key, key);

Which fails with System.ArgumentException: Expected a public key Parameter name: publicParameter . 其中System.ArgumentException: Expected a public key Parameter name: publicParameter失败System.ArgumentException: Expected a public key Parameter name: publicParameter

My question is: How to get the public key from a private key? 我的问题是:如何从私钥获取公钥?

I'm a little clumsy with the Bouncycastle C# library but I think the way to do this is to explicitly make a new key object using the appropriate components of the private key. 我对Bouncycastle C#库有点笨拙,但我认为这样做的方法是使用私钥的适当组件显式创建一个新的密钥对象。 Example

// Make an rsa keypair for testing

var rand = new SecureRandom();
var keyGenParams = new RsaKeyGenerationParameters(
        new BigInteger("65537"), rand, 1024, 64
    );
var rsaKeyGen = new RsaKeyPairGenerator();
rsaKeyGen.Init(keyGenParams);
var rsaKeyPair = rsaKeyGen.GenerateKeyPair();
var rsaPriv = (RsaPrivateCrtKeyParameters)rsaKeyPair.Private;

// Make a public from the private

var rsaPub = new RsaKeyParameters(false, rsaPriv.Modulus, rsaPriv.PublicExponent);

// Try it out

var rsaKeyPair2 = new AsymmetricCipherKeyPair(rsaPub, rsaPriv);

The downside of this approach is that it requires a concrete instance of a specific kind of asymmetric key; 这种方法的缺点是它需要特定种类的非对称密钥的具体实例; it does not work with the abstract asymmetric key classes. 它不适用于抽象的非对称密钥类。

It should be very simple: 它应该很简单:

AsymmetricCipherKeyPair KeyPair = (AsymmetricCipherKeyPair)reader.ReadObject();

Then: 然后:

var pubKey = KeyPair.public;

Thanks to help from James K Polk, here is what I came up with 感谢James K Polk的帮助,这就是我想出的

    AsymmetricCipherKeyPair GetKeyPairFromPrivateKey(AsymmetricKeyParameter privateKey)
    {
        AsymmetricCipherKeyPair keyPair = null;
        if (privateKey is RsaPrivateCrtKeyParameters rsa)
        {
            var pub = new RsaKeyParameters(false, rsa.Modulus, rsa.PublicExponent);
            keyPair = new AsymmetricCipherKeyPair(pub, privateKey);
        }
        else if (privateKey is Ed25519PrivateKeyParameters ed)
        {
            var pub = ed.GeneratePublicKey();
            keyPair = new AsymmetricCipherKeyPair(pub, privateKey);
        }
        else if (privateKey is ECPrivateKeyParameters ec)
        {
            var q = ec.Parameters.G.Multiply(ec.D);
            var pub = new ECPublicKeyParameters(ec.AlgorithmName, q, ec.PublicKeyParamSet);
            keyPair = new AsymmetricCipherKeyPair(pub, ec);
        }
        if (keyPair == null)
            throw new NotSupportedException($"The key type {privateKey.GetType().Name} is not supported.");

        return keyPair;
    }

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

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