Signature
Sign and verify a message with a HMAC digest
Uses ring::hmac
⮳ to creates a ring::signature::Signature
⮳ of a string then verifies the signature is correct.
// An error with absolutely no details (on purpose) use ring::error::Unspecified; use ring::hmac; use ring::rand; use ring::rand::SecureRandom; fn main() -> Result<(), Unspecified> { // 1. Create a key let key; { let mut key_value = [0u8; 48]; let rng = rand::SystemRandom::new(); rng.fill(&mut key_value)?; // Construct an HMAC signing key using the given digest algorithm // and key value. `key_value`` should be a value generated with // a secure random number generator. key = hmac::Key::new(hmac::HMAC_SHA256, &key_value); } // 2. Sign a message let message = "Legitimate and important message."; let signature = hmac::sign(&key, message.as_bytes()); // 3. Calculates the HMAC of data using the signing key, // and verifies whether the resultant value equals the signature. hmac::verify(&key, message.as_bytes(), signature.as_ref())?; println!("Message verified."); Ok(()) }
Compute digital signatures
For more algorithms, see Rust Crypto Signatures:
ed25519
This crate is a support library for Edwards Digital Signature Algorithm (EdDSA) over Curve25519 (as specified in RFC 8032), providing signature type definitions and PKCS#8 private key decoding/encoding support.
It doesn't contain an implementation of Ed25519, but instead contains an ed25519::Signature type which other crates can use in conjunction with the signature::Signer and signature::Verifier traits.
// // COMING SOON
ed25519-dalek
ed25519-dalek
contains ed25519 EdDSA key generation, signing, and verification algorithms in pure Rust.
use ed25519_dalek::Signature; use ed25519_dalek::Signer; use ed25519_dalek::SigningKey; use ed25519_dalek::Verifier; use ed25519_dalek::VerifyingKey; use rand::rngs::OsRng; // `ed25519` key generation, signing, and verification. fn main() -> anyhow::Result<()> { // First, we need to generate a Keypair, which includes both public and // secret halves of an asymmetric key. To do so, we need a // cryptographically secure pseudorandom number generator (CSPRNG). // For this example, we'll use the operating system's builtin PRNG: let mut csprng = OsRng; let signing_key: SigningKey = SigningKey::generate(&mut csprng); // Message to be signed let message = b"Hello, world!"; // Sign the message let signature: Signature = signing_key.sign(message); // Verify the signature assert!(signing_key.verify(message, &signature).is_ok()); // Anyone else, given the public half of the signing_key can also easily // verify this signature: let verifying_key: VerifyingKey = signing_key.verifying_key(); assert!(verifying_key.verify(message, &signature).is_ok()); // VerifyingKeys, SecretKeys, SigningKeys, and Signatures can be // serialised into byte-arrays by calling `to_bytes`. Ok(()) }
ecdsa
ecdsa
contains a pure Rust implementation of the Elliptic Curve Digital Signature Algorithm (ECDSA) as specified in FIPS 186-4 (Digital Signature Standard), providing RFC6979 deterministic signatures as well as support for added entropy.
// // Elliptic Curve Digital Signature Algorithm (ECDSA) as specified in FIPS // 186-4 // (Digital Signature Standard). https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm // // - A pair of private and public keys are created: data encrypted with // either // key can only be decrypted with the other. // // - A signing entity that published their public key can generate an // encrypted // signature // // using their private key, and a verifier can assert the source if it is // // decrypted correctly using the declared public key. // // The `ecdsa` crate crate provides generic ECDSA support, which can be used // // with the `k256`, `p256`, `p384` crates. For this example, add to your // // `Cargo.toml`: // // p256 = { version = "0.13.2" } # or latest // use p256::SecretKey; // use p256::ecdsa::Signature; // use p256::ecdsa::SigningKey; // use p256::ecdsa::VerifyingKey; // use p256::ecdsa::signature::Signer; // use p256::ecdsa::signature::Verifier; // // An interface over the operating-system's random data source // use p256::elliptic_curve::rand_core::OsRng; // // Serialize a private key object to a PKCS#8 encoded document. // // (Public-Key Cryptography Standards (PKCS) #8) // use p256::pkcs8::EncodePrivateKey; // fn main() { // // 1. Generate a random secret key // let secret_key = SecretKey::random(&mut OsRng); // // 2. Derive public key // let public_key = PublicKey::from(&secret_key); // // 3. Encode the secret key to PKCS#8 format (for storage/transmission) // // PKCS#8 is a format for cryptographic private keys, often containing // pairs of private and public keys. let private_key_der = // secret_key.to_pkcs8()?; // Get it in PEM format. The PEM text encoding is // a Base64 representation. let private_key_pem = private_key_der.to_pem()?; // // In a real world application, never print or store private keys in // plain // text! // println!("Private Key (PEM):\n{}\n", private_key_pem); // // 4. Create a message to sign // let message = b"Hello, world!"; // // 5. Sign the message using the secret key // let signature: Signature = secret_key.ecdsa_sign(message); // // Print the signature in hex format // println!("Signature: {:x?}", signature); // // 6. Verify the signature using the public key // assert!(public_key.verify(message, &signature).is_ok()); // println!("Message signature verified successfully"); // }
dsa
Pure Rust implementation of the Digital Signature Algorithm (DSA) as specified in FIPS 186-4 (Digital Signature Standard), providing RFC6979 deterministic signatures as well as support for added entropy.
use p256::ecdsa::Signature; use p256::ecdsa::SigningKey; use p256::ecdsa::VerifyingKey; use p256::ecdsa::signature::Signer; use p256::ecdsa::signature::Verifier; use p256::elliptic_curve::rand_core::OsRng; fn main() { // Generate a signing key let signing_key = SigningKey::random(&mut OsRng); // Create a verifying key from the signing key let verifying_key = VerifyingKey::from(&signing_key); // Message to be signed let message = b"Hello, world!"; // Sign the message let signature: Signature = signing_key.sign(message); // Verify the signature assert!(verifying_key.verify(message, &signature).is_ok()); println!("Message signature verified successfully"); // Print the signature in hex format println!("Signature: {:x?}", signature); }