Signature

Sign and verify a message with a HMAC digest

ring ring-crates.io ring-github ring-lib.rs cat-cryptography cat-no-std

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. Use in conjunction with the ed25519-dalek crate.
  • ecdsa
  • dsa

ed25519

ed25519-website ed25519 ed25519-crates.io ed25519-github ed25519-lib.rs cat-cryptography cat-no-std

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-website ed25519-dalek ed25519-dalek-crates.io ed25519-dalek-github ed25519-dalek-lib.rs cat-cryptography cat-no-std

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-website ecdsa ecdsa-crates.io ecdsa-github ecdsa-lib.rs cat-cryptography cat-no-std

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

dsa-website dsa dsa-crates.io dsa-github dsa-lib.rs cat-cryptography cat-no-std

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);
}