I'm trying to get BouncyCastle's AsymmetricKeyParameter object from a byte array that contains a public key. The particular example I'm facing is a RSA public key encoded in the simplest way possible, namely as a DER sequence with two INTEGER objects, modulus and public exponent; however, I cannot assume it's always going to be RSA (could also be ECDSA).
Examples I've found on the web suggest using PublicKeyFactory.CreateKey, I do it like this:
Asn1InputStream ais = new Asn1InputStream(content);
Asn1Object publicKey = ais.ReadObject();
var pubkeyParams = PublicKeyFactory.CreateKey(publicKey.GetEncoded());
Unfortunately, this gives me an exception "Unknown object in GetInstance: Org.BouncyCastle.Asn1.DerInteger\nParameter name: obj"
I guess that has something to do with how the key is encoded in that byte array. Unfortunately that's not something I have control of; but it's not like it's completely botched either, since OpenSSL command line utility doesn't protest when I run openssl rsa -in publicKey.bin -RSAPublicKey_in -inform DER -text
on the bin file with key data.
I'd appreciate any help in how to proceed. I'm thinking about trying to parse key data as RSA, if that doesn't work then as ECDSA, then fold when exception happens. I'm not sure how to do it with BC though...
PublicKeyFactory
is for encodings of the X.509 ASN.1 type SubjectPublicKeyInfo
. If you want to be able to work with public keys in a generic way it would be preferable to be using SubjectPublicKeyInfo
for public keys (and PKCS#8 PrivateKeyInfo
for private keys).
It sounds like you have an ASN.1 RSAPublicKey
encoding, in which case you can adjust your example code to use:
var rsaKey = Org.BouncyCastle.Asn1.X509.RsaPublicKeyStructure.GetInstance(publicKey);
var pubkeyParams = new RsaKeyParameters(false, rsaKey.Modulus, rsaKey.PublicExponent);
ECDSA keys can likewise be in several possible formats, so it's probably best to take that as a separate question.