6

I'm trying to save RsaKeyParameter Public Key into an SQL database. I get an error that Bouncy Castle can't convert RsaKeyParameters to bytes.

Using BouncyCastle c#.

I've generate an RSA key pair, extracted the private and public keys into variables. I then need to store the public key for verification at a later stage in the application.

I found a post on converting to byte then string as follows;

byte[] serializedPublicBytes = 
publicKeyInfo.ToAsn1Object().GetDerEncoded();
string serializedPublic = Convert.ToBase64String(serializedPublicBytes);

but it doesn't like ToAsn1Object. Just to add this is an example, I'm aware my variable names are different.

        RsaKeyPairGenerator rsaKeyPairGen = new RsaKeyPairGenerator();
        rsaKeyPairGen.Init(new KeyGenerationParameters(new SecureRandom(), 2048));
        AsymmetricCipherKeyPair keyPair = rsaKeyPairGen.GenerateKeyPair();

        RsaKeyParameters PrivateKey = (RsaKeyParameters)keyPair.Private;
        RsaKeyParameters PublicKey = (RsaKeyParameters)keyPair.Public;

The public key should to byte, then string, to save into the database.

1 Answer 1

12

The public key can be converted to the X.509/SubjectPublicKeyInfo-ASN.1/DER-format using BouncyCastle. This is a binary format from which a string can be generated using Base64-encoding:

byte[] publicKeyDer = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey).GetDerEncoded();
String publicKeyDerBase64 = Convert.ToBase64String(publicKeyDer);

Here, publicKey is the public key stored in the RsaKeyParameters-instance. The reverse process is:

byte[] publicKeyDerRestored = Convert.FromBase64String(publicKeyDerBase64);
RsaKeyParameters publicKeyRestored = (RsaKeyParameters)PublicKeyFactory.CreateKey(publicKeyDerRestored);

Detailed descriptions of the X.509/SubjectPublicKeyInfo- and ASN.1/DER-format can be found here and here, respectively.

Both, publicKeyDer (as hex-string) and publicKeyDerBase64, can be displayed in an ASN.1-Editor, e.g. https://lapo.it/asn1js/

Another approach is to create the PEM-format using the Org.BouncyCastle.OpenSsl.PEMWriter- and Org.BouncyCastle.OpenSsl.PEMReader-class (not to be confused with Org.BouncyCastle.Utilities.IO.Pem.PEMWriter/PEMReader):

TextWriter textWriter = new StringWriter();
PemWriter pemWriter = new PemWriter(textWriter);
pemWriter.WriteObject(publicKey);
pemWriter.Writer.Flush();
String publicKeyPEM = textWriter.ToString();

and the reverse is:

TextReader textReader = new StringReader(publicKeyPEM);
PemReader pemReader = new PemReader(textReader);
RsaKeyParameters publicKeyRestored = (RsaKeyParameters)pemReader.ReadObject();

The PEM-format is essentially a textual representation of the DER-format using an implicit Base64-encoding (e.g. explained here) and a header (-----BEGIN PUBLIC KEY-----) and footer (-----END PUBLIC KEY-----). Therefore, the Base64-encoded part is identical (if line breaks are ignored) for both, publicKeyDerBase64 and publicKeyPEM.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! This worked. I converted to PEM and used the reverse to use in the signature verification process.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.