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