Dan Ellis Dan Ellis - 7 days ago 6
C# Question

Generate X.509 SubjectPublicKeyInfo/OpenSSL PEM public key from self-signed certificate

I'm building a stub for a third-party API. Requests made to the third-party have to be encrypted using a public key provided. As part of the stub I would like to decrypt the incoming request.

I plan on changing the public key my calling code uses so that I can decrypt it using my private key.

I have a self-signed certificate that's being used on other parts of the application that I was hoping I could just re-use.

The problem I'm having is getting the public key out of the certificate in the format I need.

Based on a couple of answers by Ian Boyd (this one and this one), the format I need to get the public key into is "X.509 SubjectPublicKeyInfo/OpenSSL PEM", that is the format of the key I receive from my third-party. For example:

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcZ/r0nvJyHUUstIB5BqCUJ1CC
Cd1nzle4bEpPQJ/S0Wn7mV2FDAeh+UcbVhZu9n+5zypYNjeZKapPqBLoT8eCK51y
Kpzeb8LuEm3P8PK4xN18XBrIF1GprN8IIgSdK9f5SwnemutcURrY+PlWnvj7N5s/
03RlJA3/NHVXpPW/VQIDAQAB
-----END PUBLIC KEY-----


I've tried using the X509Certificate2.GetPublicKey method, and then
base64
encoding it, but that gives me the key in "PEM DER ASN.1 PKCS#1 RSA" format.

Does anyone know how I can get the public key in the format I need? I don't necessarily need the key in code, I just need a string value I can store in my database.

My certificate/private/public/cryptography knowledge is limited to any help would be much appreciated!

Answer

I was able to build the public key in the format I required using Bouncy Castle's PemWriter:

var cert = Org.BouncyCastle.Security.DotNetUtilities.FromX509Certificate(x509certificate);

using (var stringWriter = new StringWriter())
{
    var pemWriter = new Org.BouncyCastle.OpenSsl.PemWriter(stringWriter);
    pemWriter.WriteObject(cert.GetPublicKey());
    var pem = stringWriter.ToString();
}