Java – how to get publickey object from EC public key byte?
I am developing an application. I need to verify sha256withecdsasignatures with the help of secp256r1 (NIST p-256, p-256, prime256v1) public key
Public keys are generated by different applications at an earlier point in time and stored in my database in hexadecimal encoding Here, the format of the hexadecimal string is equivalent to the hexadecimal string x.pem generated by OpenSSL ecparam - genkey - name secp256r1 - out when OpenSSL EC - in x.pem - noout - text is called in the file x.pem previously generated by OpenSSL ecparam - name secp256r1 - out Messages and signatures are received from different applications Please consider the following test data:
// Stored in Database byte[] pubKey = DatatypeConverter.parseHexBinary("049a55ad1e210cd113457ccd3465b930c9e7ade5e760ef64b63142dad43a308ed08e2d85632e8ff0322d3c7fda14409eafdc4c5b8ee0882fe885c92e3789c36a7a"); // Received from Other Application byte[] message = DatatypeConverter.parseHexBinary("54686973206973206a75737420736f6d6520706f696e746c6573732064756d6d7920737472696e672e205468616e6b7320616e7977617920666f722074616b696e67207468652074696d6520746f206465636f6465206974203b2d29"); byte[] signature = DatatypeConverter.parseHexBinary("304402205fef461a4714a18a5ca6dce6d5ab8604f09f3899313a28ab430eb9860f8be9d602203c8d36446be85383af3f2e8630f40c4172543322b5e8973e03fff2309755e654");
This should now be a valid signature
My goal is to verify the signature on the message using Java and / or bouncy castle encryption APIs I created a method isvalidsignaturefor:
private static boolean isValidSignature(byte[] pubKey,byte[] message,byte[] signature) throws NoSuchAlgorithmException,NoSuchProviderException,InvalidKeyException,SignatureException,InvalidKeySpecException { Signature ecdsaVerify = Signature.getInstance("SHA256withECDSA",new BouncyCastleProvider()); ecdsaVerify.initVerify(getPublicKeyFromHex(pubKey)); ecdsaVerify.update(message); return ecdsaVerify.verify(signature); }
I tried to extract the public key:
KeyFactory. generatePublic:
private static PublicKey getPublicKeyFromHex(byte[] pubKey) throws NoSuchAlgorithmException,InvalidKeySpecException { KeyFactory fact = KeyFactory.getInstance("ECDSA",new BouncyCastleProvider()); return fact.generatePublic(new X509EncodedKeySpec(pubKey)); }
But this throws Java security. Spec.invalidkeyspecexception (Der length exceeds 4 bytes: 26) What can I do to parse this?
Solution
Bouncy castle example code on elliptic curve key pair generation and key factories brings me very close
Once I managed to create an ECDSA key factory and a curve specification for secp256r1 / NIST p-256 / p-256 / prime256v1 curves, I was able to use ecpointutil Decodepoint to get a curve point Then, I can generate a public key specification to enable me to generate the following public keys:
private PublicKey getPublicKeyFromBytes(byte[] pubKey) throws NoSuchAlgorithmException,InvalidKeySpecException { ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("prime256v1"); KeyFactory kf = KeyFactory.getInstance("ECDSA",new BouncyCastleProvider()); ECNamedCurveSpec params = new ECNamedCurveSpec("prime256v1",spec.getCurve(),spec.getG(),spec.getN()); ECPoint point = ECPointUtil.decodePoint(params.getCurve(),pubKey); EcpublicKeySpec pubKeySpec = new EcpublicKeySpec(point,params); EcpublicKey pk = (EcpublicKey) kf.generatePublic(pubKeySpec); return pk; }