0

I have a simple task but I don't know how to do it. I want to generate a public key from a private key with Bouncycastle in C#.

using (var reader = new StringReader(privateKey))
{
    var pemReader = new PemReader(reader);
    // ...
}

I found a lot of examples that used this:

AsymmetricCipherKeyPair keyPair = (AsymmetricCipherKeyPair)pemReader.ReadObject();
var publicKey = keyPair.Public;

But it throws an exception:

Unable to cast object of type 'Org.BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParameters' to type 'Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair

What do I need to change to get it working?


Edit:

I used the example from @James K Polk and got it working.

using (var reader = new StringReader(privateKey))
{
    var pemReader = new PemReader(reader);
    var pemObject = pemReader.ReadObject();

    var rsaPrivateCrtKeyParameters = (RsaPrivateCrtKeyParameters)pemObject;
    var rsaKeyParameters = new RsaKeyParameters(false, rsaPrivateCrtKeyParameters.Modulus, rsaPrivateCrtKeyParameters.PublicExponent);
}
Shamshiel
  • 2,051
  • 3
  • 31
  • 50
  • 1
    `PemReader.ReadObject` gets you an object of type `RsaPrivateCrtKeyParameters`, and not the expected `AsymmetricCipherKeyPair`. That means that PemReader found the source stream to contain only a "PRIVATE KEY" component, or is unable to extract the public key part for some other reason. I guess the problem is your source data. Can you show a dump of the source (with PK info obfuscated if sensitive)? – Cee McSharpface Aug 23 '18 at 11:33
  • I guess the problem is that I only have a private key but isn't it possible to create a public key with a private key? – Shamshiel Aug 23 '18 at 13:21
  • 1
    not in all algorithms. it is usually possible though, especially for RSA ([see also here](https://stackoverflow.com/a/1373088/1132334)). what is your input, exactly? – Cee McSharpface Aug 23 '18 at 15:58

1 Answers1

1

As stated in the comment by @dlatikay it is not necessarily true that a public key can be derived from a private key, so there is no GetPublic method or property available on an abstract private key. However, most private key classes contain enough information to easily derive the public key. Here is an example for Bouncycastle RSA private keys:

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

Also, note that RsaPrivateCrtKeyParameters is a subclass of RsaKeyParameters so, depending on how you use it, it may be possible to use the RsaPrivateCrtKeyParameters instance directly where a public key is expected.

President James K. Polk
  • 40,516
  • 21
  • 95
  • 125