I am able to create a public/private ecdsa key in Rust, how can I store the keys for further use? I can't seem to find a method that will export the key.
use p256::{ecdsa::{SigningKey, Signature, signature::Signer}};
use rand_core::OsRng; // requires 'getrandom' feature
fn main() {
// Signing
let signing_key = SigningKey::random(&mut OsRng); // Serialize with `::to_bytes()`
let message = b"ECDSA proves knowledge of a secret number in the context of a single message";
let signature = signing_key.sign(message);
// Verification
use p256::ecdsa::{VerifyingKey, signature::Verifier};
let verifying_key = VerifyingKey::from(&signing_key); // Serialize with `::to_encoded_point()`
assert!(verifying_key.verify(message, &signature).is_ok());
}
There are many different ways to represent keys. Internally, it's a byte array that can be dumped as such directly. But for compatibility, you probably want a more standardized, human readable format.
The most common one is the PEM format.
To get a PEM, you cannot construct SigningKey
and VerifyingKey
directly. You need to create a SecretKey
and a PublicKey
. They can be stored and loaded to/from the PEM format.
You can then convert the SecretKey
to a SigningKey
and the PublicKey
to a VerifyingKey
.
Be aware that you need to enable the pem
feature for the p256
dependency:
p256 = { version = "0.11", features = ["pem"] }
use p256::{
ecdsa::{
signature::{Signer, Verifier},
SigningKey, VerifyingKey,
},
pkcs8::EncodePrivateKey,
PublicKey, SecretKey,
};
use rand_core::OsRng;
fn main() {
// Generate secret key
let secret_key = SecretKey::random(&mut OsRng);
// Store secret key
let secret_key_serialized = secret_key
.to_pkcs8_pem(Default::default())
.unwrap()
.to_string();
println!("Secret Key: \n{}", secret_key_serialized);
// Load secret key
let secret_key = secret_key_serialized.parse::<SecretKey>().unwrap();
// Derive public key
let public_key = secret_key.public_key();
// Store public key
let public_key_serialized = public_key.to_string();
println!("Public Key: \n{}", public_key_serialized);
// Load public key
let public_key = public_key_serialized.parse::<PublicKey>().unwrap();
// Signing
let signing_key: SigningKey = secret_key.into();
let message = b"ECDSA proves knowledge of a secret number in the context of a single message";
let signature = signing_key.sign(message);
// Verification
let verifying_key: VerifyingKey = public_key.into();
assert!(verifying_key.verify(message, &signature).is_ok());
}
Secret Key:
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQguKslF8gIC/Fm36Yk
SK2qZ4MXbUg/ZwCJwY9OmzRzkOehRANCAAQrRw99abOvHAPdz79CkuihXfaKZqx+
ZUG6iQRDzZy0c+gw20KeevA4gXKnW0nFK8PDmOgBprCU/uHf4vpMbqgo
-----END PRIVATE KEY-----
Public Key:
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEK0cPfWmzrxwD3c+/QpLooV32imas
fmVBuokEQ82ctHPoMNtCnnrwOIFyp1tJxSvDw5joAaawlP7h3+L6TG6oKA==
-----END PUBLIC KEY-----