Reputation: 5648
I am trying to decode a PublicKey in Rust and it fails if I use a byte slice or a PEM encoded key. The example docs merely show it decoding what it encoded, but I generated these keys from openssl. Here is the code I am using:
use std::io::{BufRead, BufReader, stdin};
use libp2p::identity::ed25519::{PublicKey};
fn main() {
BufReader::new(stdin()).lines()
.map(|l| l.unwrap())
.for_each(|l| {
match PublicKey::decode(hex::decode(l).unwrap().as_slice()) {
Ok(_pk) => println!("pk decoded"),
Err(e) => println!("{}", e.to_string())
}
});
}
output:
302A300506032B6570032100EDBF0FC3EA90291E030EA95C3D9617C347056FA3126089A3960791C601BF9A72
Key decoding error: Ed25519 public key
I generated the keys using openssl as such:
/usr/local/Cellar/openssl@3/3.0.2/bin/openssl genpkey -algorithm Ed25519 -out ed25519key.pem
/usr/local/Cellar/openssl@3/3.0.2/bin/openssl pkey -in ed25519key.pem -pubout
Which gives a public key of:
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEA7b8Pw+qQKR4DDqlcPZYXw0cFb6MSYImjlgeRxgG/mnI=
-----END PUBLIC KEY-----
I've tried passing this raw pem as well as the decoded bytes too:
302A300506032B6570032100EDBF0FC3EA90291E030EA95C3D9617C347056FA3126089A3960791C601BF9A72
Upvotes: 1
Views: 1102
Reputation: 5613
libp2p::identity::ed25519::PublicKey
is just a wrapper around ed25519_dalek::PublicKey
, and when you call decode()
, it simply calls ed25519_dalek::PublicKey::from_bytes()
and returns the struct containing the result.
The reason it is failing is because from_bytes()
expects a raw public key, which is 32 bytes; however, the output from openssl
isn't a raw key, but rather it is apparently a 12 byte ASN.1 header followed by the 32 byte raw key. So to get the actual raw key you need to discard the first 12 bytes. You can either do that in your Rust code, or do it up front when you generate the key.
To get only the (base64 encoded) 32 byte key from openssl
, you can use the following command:
openssl pkey -in ed25519key.pem -pubout -outform DER | tail -c +13 | openssl base64
Upvotes: 4