Search code examples
bouncycastleprivate-keyeddsa

How to decide publicKey is raw bits or encoded and is private key is always pkcs8 encoded?


Recently I'm reading code of bouncycastle(java), I noticed that when using EdDSA, we are using org.bouncycastle.asn1.x509.SubjectPublicKeyInfo#getPublicKeyData to get publicKey in org.bouncycastle.jcajce.provider.asymmetric.edec.BCEdDSAPublicKey#populateFromPubKeyInfo. But when using RSA we are using org.bouncycastle.asn1.x509.SubjectPublicKeyInfo#parsePublicKey in org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPublicKey#populateFromPublicKeyInfo.

The comment of parsePublicKey is for when the public key is an encoded object - if the bitstring can't be decoded this routine throws an IOException. and getPublicKeyData's is for when the public key is raw bits..

I am confused that how can we decide which method to use? Is this written in EdDSA spec or somewhere? I googled around and found nothing.

Edit:

Following is the info I collected, corret me if I'm wrong.

Both EdRsa publicKey and RSA publicKey is ASN.1 encoded,the use of org.bouncycastle.asn1.x509.SubjectPublicKeyInfo#getPublicKeyData is simply because EdRsa publicKey only contains one component (a simple byte array) while rsa key contains two component(modules and publicExp).

Almost all private key is pkcs#8 encoded, after all it's named "Private-Key Information Syntax Standard". But rsa privateKey can also encoded in pkcs#1 which cames before pkc#8, and those two formats can be converted back and force.


Solution

  • RFC 5280 specifies that X.509 public keys be encoded in a SubjectPublicKeyInfo ASN.1 SEQUENCE. This has two parts: the first ('algorithm') is an AlgorithmIdentifier which tells you what algorithm the key is for, and the second ('subjectPublicKey') is an ASN.1 BIT STRING whose interpretation is algorithm-dependent.

    In the case of EdDSA, its use in X.509 was specified in RFC 8410. That RFC provides the OBJECT IDENTIFIER to use in the 'algorithm' for Ed25519/Ed448 and retains the public key format specified in the original EdDSA RFC - RFC 8032 i.e. a byte string, so that's what goes in the 'subjectPublicKey'.