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.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With