Reputation: 612
I have an byte[] encodedKeyBytes
and I want to create the associated Public Key.
// spec for P-256 curve
ECParameterSpec params = ECNamedCurveTable.getParameterSpec("prime256v1");
ECPublicKeySpec pubKey = new ECPublicKeySpec(
params.getCurve().decodePoint(encodedKeyBytes), params);
Exception in thread "main" java.lang.IllegalArgumentException: Invalid point encoding 0x-5c at org.bouncycastle.math.ec.ECCurve.decodePoint(Unknown Source)
Here after is the whole method :
public PublicKey generatePublicKeyFrom(byte[] encodedKeyBytes)
throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException {
// spec for P-256 curve
ECParameterSpec params = ECNamedCurveTable.getParameterSpec("prime256v1");
ECPublicKeySpec pubKey = new ECPublicKeySpec(
params.getCurve().decodePoint(encodedKeyBytes), params);
KeyFactory kf = KeyFactory.getInstance("ECDH", "BC");
PublicKey pb = kf.generatePublic(pubKey));
System.out.println("public key: " + pb;
return pb;
}
I read some documentation it seems the issue is linked to the size and format of the array byte. Is there any way to generate that public key based from the actual byte array or do I have to actually retrieve the params used to create that byte array ?
The byte array consists of the following bytes:
a401022001215820e4706de318a40d0bd8648b7907b0283f7445370241ff1fdd77f08d6a598be90222582079767fbe391223f61dcd5e980133a035b4918f6f9de41b3ceb8d801860df8859
giving the CBOR encoding:
A4 # map(4)
01 # unsigned(1)
02 # unsigned(2)
20 # negative(0)
01 # unsigned(1)
21 # negative(1)
58 20 # bytes(32)
E4706DE318A40D0BD8648B7907B0283F7445370241FF1FDD77F08D6A598BE902 # "\xE4pm\xE3\x18\xA4\r\v\xD8d\x8By\a\xB0(?tE7\x02A\xFF\x1F\xDDw\xF0\x8DjY\x8B\xE9\x02"
22 # negative(2)
58 20 # bytes(32)
79767FBE391223F61DCD5E980133A035B4918F6F9DE41B3CEB8D801860DF8859 # "yv\x7F\xBE9\x12#\xF6\x1D\xCD^\x98\x013\xA05\xB4\x91\x8Fo\x9D\xE4\e<\xEB\x8D\x80\x18`\xDF\x88Y"
Thank you !
Upvotes: 1
Views: 1743
Reputation: 612
For those wondering how to do create the public key from the COSE_Key_structure :
public PublicKey generatePublicKeyFromECDH(byte[] encodedKeyBytes)
throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException {
ECParameterSpec params2 = ECNamedCurveTable.getParameterSpec("secp256r1");
ECPointECDH ecPoint = null;
ObjectMapper mapper = new ObjectMapper(new CBORFactory());
try {
ecPoint = mapper.readValue(encodedKeyBytes, ECPointECDH.class);
} catch (IOException e) {
e.printStackTrace();
}
ECPublicKeySpec publicKeySpec = new ECPublicKeySpec(ecPoint.getEcPoint(), params2);
KeyFactory kf = KeyFactory.getInstance("EC", "BC");
PublicKey pb = kf.generatePublic(publicKeySpec);
return pb;
}
And here is the mapper.
public ECPointECDH deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
JsonNode node = p.readValueAsTree();
byte[] x10 = node.get("-2").binaryValue();
byte[] y10 = node.get("-3").binaryValue();
String x = Utils.convertBytesToHex(x10);
String y = Utils.convertBytesToHex(y10);
ECNamedCurveParameterSpec params = ECNamedCurveTable.getParameterSpec("secp256r1");
ECCurve curve = params.getCurve();
ECPoint point = curve.decodePoint(Hex.decode("04" + x + y));
return new ECPointECDH(point);
}
Upvotes: 0
Reputation: 93948
Bouncy Castle doesn't have a native CBOR decoding.
If you give it a public key point it will try and parse a X9.62 formatted point, which starts with a byte valued 02
or 03
for a compressed point and 04
for an uncompressed point. Compression in this case means that the Y-coordinate is calculated from the X-coordinate according to an EC-specific algorithm.
If you want to create a point to decompress giving the current point you will first have to parse the point using a CBOR library. Then you'd have to stick the X-coordinate and Y-coordinate together and put 04
in front of it, which would give you:
04 E4706DE318A40D0BD8648B7907B0283F7445370241FF1FDD77F08D6A598BE902 79767FBE391223F61DCD5E980133A035B4918F6F9DE41B3CEB8D801860DF8859
Of course if you could find a COSE library you'd be better off. There seems to be one generated by the COSE workgroup, but it looks unmaintained to me.
Upvotes: 1