ED25519 public key creation from bytes fails

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

ED25519 public key creation from bytes fails

Fausto Spoto
This post was updated on .
Hi!

I’m writing a Java application on top of the Tendermint blockchain. The
application receives a data structure pk from Tendermint, that represents
an ED25519 public key. I would like to transform it into a
java.security.PublicKey by using bouncycastle version 1.67. It is
impossible to report the full code here, since the integration with
Tendermint is far from simple. However, these are the interesting lines
that I wrote:

System.out.println("key type: " + pk.getType());
byte[] bytes = pk.getData().toByteArray();
String publicKeyBase64 = new String(Base64.getEncoder().encode(bytes));
System.out.println("public key as Base64: " + publicKeyBase64);
System.out.println("bytes.length = " + bytes.length);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
KeyFactory keyFactory = KeyFactory.getInstance("ed25519", "BC");
PublicKey publicKey = keyFactory.generatePublic(keySpec); // exception here

These lines print:

key type: ed25519
public key as Base64: kVdnrqoFQZOn2K2J0F5wD6nsJtTpiLZdIfQQOf8n6ps=
bytes.length = 32

which looks correct to me, since it coincides with the public key that I
see in the configuration file of Tendermint. Also the length of the byte
array looks correct to me, since an ED25519 public key is 256 bits
long, ie, 32 bytes long.

However, the last line throws an exception:

java.security.spec.InvalidKeySpecException: encoded key spec not
recognized: failed to construct sequence from byte[]: corrupted stream -
out of bounds length found: 87 >= 32

I'm lost here. What could be the reason for that failure?
Reply | Threaded
Open this post in threaded view
|

Re: ED25519 public key creation from bytes fails

David Hook-3

The public point by itself doesn't constitute an X509EncodedKeySpec. The class expects an encoding of a SubjectPublicKeyInfo object. You'll find an example of how one of these can be created in org.bouncycastle.crypto.utilSubjectPublicKeyInfoFactory.

Regards,

David

On 18/12/20 8:08 am, Fausto Spoto wrote:
Hi!

I’m writing a Java application on top of the Tendermint blockchain. The application receives a data structure pk from Tendermint, that represents an ED25519 public key. I would like to transform it into a java.security.PublicKey by using bouncycastle version 1.67. It is impossible to report the full code here, since the integration with Tendermint is far from simple. However, these are the interesting lines that I wrote:

System.out.println("key type: " + pk.getType());
byte[] bytes = pk.getData().toByteArray();
String publicKeyBase64 = new String(Base64.getEncoder().encode(bytes));
System.out.println("public key as Base64: " + publicKeyBase64);
System.out.println("bytes.length = " + bytes.length);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
PublicKey publicKey = keyFactory.generatePublic(keySpec); // exception here

These lines print:

key type: ed25519
public key as Base64: kVdnrqoFQZOn2K2J0F5wD6nsJtTpiLZdIfQQOf8n6ps=
bytes.length = 32

which looks correct to me, since it coincides with the public key that I see in the configuration file of Tendermint. Also the length of the byte array looks correct to me, since an ED25519 public key is 256 bits long, ie, 32 bytes long.

However, the last line throws an exception:

java.security.spec.InvalidKeySpecException: encoded key spec not recognized: failed to construct sequence from byte[]: corrupted stream - out of bounds length found: 87 >= 32

I'm lost here. What could be the reason for that failure?