Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert RSA public key to string using BouncyCastle c#

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.

like image 969
MarkC Avatar asked Jan 27 '23 09:01

MarkC


1 Answers

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.

like image 115
Topaco Avatar answered Feb 09 '23 01:02

Topaco