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.
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.
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'.