I have a raw (r,s) format ECDSA NIST P-256 public key. It seems that there is no simple way to load it into an object that implements java.security.interfaces.ECPublicKey.
What is the cleanest way to load a 64 byte public key so that it can be used to check signatures?
This answer is going to be tough if we do this using
ECPublicKeySpec
. So lets cheat a bit:Usage:
I generated the head using:
called by:
The idea behind this is to create an X509 encoded key, which happily ends with the public point
w
at the end (the bytes before that contain the ASN.1 DER encoding of the OID of the named curve and structural overhead, ending with byte04
indicating an uncompressed point). Then we replace the "random" pointw
at the end with yourw
and we decode it again.Java 7 required for the EC functionality and Java 8 for the Base 64 encoder / decoder, no additional libraries and stuff. Note that this will actually display the public key as a named curve when printed out, something the other solutions won't do.
The EC Public Key is a point that consists of x and y co-ordinate. I wrote the following code segment once to convert EC x, y point to
publicKey
object. Hope this will help you. For your information:Example EC Public Key Point for P-256:
BC Provider: You need Bouncy Castle provider. I used bcprov-jdk15on-149.jar, but you can download the latest version from here.
EDIT: Here is
toByte()
method:But you can use your own implementation. Here is another one:
That worked for me with the help of Bouncycastle:
Java does make cryptography very long winded.
The procedure to create a public key from a given EC point:
ECPoint
object from your given co-ordinates.ECParameterSpec
object from information of your curve.ECPublicKeySpec
object from yourECPoint
and yourECParameterSpec
object.KeyFactory.generatePublic()
with yourECPublicKeySpec
object to retrieve aPublicKey
object.PublicKey
into anECPublicKey
as necessary.Example below:
It may be helpful to generate the ECParameterSpec once (perhaps in a static initializer block) for performance reasons.
Note: There is probably a much simpler way to generate the ECParameterSpec object (via named curves for example) but so far I've only found that
ECGenParameterSpec
has this feature. Let me know in comments if there is a less painful approach.To save yourself the pain of doing the above, encode your EC key under X.509, which will fully describe the key and make loading it much much easier.
In java, with the ECPublicKey, all you need to do is call
ECPublicKey.getEncoded()
and pass/save the byte array to where you need the key next. The X.509 encoded key can then be reconstructed via:where "data" is the encoded byte array.