Module ring::hmac[][src]

HMAC is specified in RFC 2104.

After a SigningKey or VerificationKey is constructed, it can be used for multiple signing or verification operations. Separating the construction of the key from the rest of the HMAC operation allows the per-key precomputation to be done only once, instead of it being done in every HMAC operation.

Frequently all the data to be signed in a message is available in a single contiguous piece. In that case, the module-level sign function can be used. Otherwise, if the input is in multiple parts, SigningContext should be used.

Use Case: Multi-party Communication

Examples: TLS, SSH, and IPSEC record/packet authentication.

The key that is used to sign messages to send to other parties should be a SigningKey; SigningContext or sign should be used for the signing. Each key that is used to authenticate messages received from peers should be a VerificationKey; verify should be used for the authentication. All of the keys should have distinct, independent, values.

Use Case: One-party Anti-tampering Protection

Examples: Signed cookies, stateless CSRF protection.

The key that is used to sign the data should be a SigningKey; SigningContext or sign should be used for the signing. Use verify_with_own_key to verify the signature using the signing key; this is equivalent to, but more efficient than, constructing a VerificationKey with the same value as the signing key and then calling verify.

Use Case: Key Derivation and Password Hashing

Examples: HKDF, PBKDF2, the TLS PRF.

All keys used during the key derivation should be SigningKeys; SigningContext should usually be used for the HMAC calculations. The code for ring::pbkdf2 and the code for ring::hkdf are good examples of how to use ring::hmac efficiently for key derivation.

Examples:

Signing a value and verifying it wasn't tampered with

use ring::{digest, hmac, rand};

let rng = rand::SystemRandom::new();
let key = hmac::SigningKey::generate(&digest::SHA256, &rng)?;

let msg = "hello, world";

let signature = hmac::sign(&key, msg.as_bytes());

// [We give access to the message to an untrusted party, and they give it
// back to us. We need to verify they didn't tamper with it.]

hmac::verify_with_own_key(&key, msg.as_bytes(), signature.as_ref())?;

Using the one-shot API:

use ring::{digest, hmac, rand};
use ring::rand::SecureRandom;

let msg = "hello, world";

// The sender generates a secure key value and signs the message with it.
// Note that in a real protocol, a key agreement protocol would be used to
// derive `key_value`.
let mut key_value = [0u8; 32];
let rng = rand::SystemRandom::new();
rng.fill(&mut key_value)?;

let s_key = hmac::SigningKey::new(&digest::SHA256, key_value.as_ref());
let signature = hmac::sign(&s_key, msg.as_bytes());

// The receiver (somehow!) knows the key value, and uses it to verify the
// integrity of the message.
let v_key = hmac::VerificationKey::new(&digest::SHA256, key_value.as_ref());
hmac::verify(&v_key, msg.as_bytes(), signature.as_ref())?;

Using the multi-part API:

use ring::{digest, hmac, rand};
use ring::rand::SecureRandom;

let parts = ["hello", ", ", "world"];

// The sender generates a secure key value and signs the message with it.
// Note that in a real protocol, a key agreement protocol would be used to
// derive `key_value`.
let mut key_value = [0u8; 48];
let rng = rand::SystemRandom::new();
rng.fill(&mut key_value)?;

let s_key = hmac::SigningKey::new(&digest::SHA384, key_value.as_ref());
let mut s_ctx = hmac::SigningContext::with_key(&s_key);
for part in &parts {
    s_ctx.update(part.as_bytes());
}
let signature = s_ctx.sign();

// The receiver (somehow!) knows the key value, and uses it to verify the
// integrity of the message.
let v_key = hmac::VerificationKey::new(&digest::SHA384, key_value.as_ref());
let mut msg = Vec::<u8>::new();
for part in &parts {
    msg.extend(part.as_bytes());
}
hmac::verify(&v_key, &msg.as_ref(), signature.as_ref())?;

Structs

Signature

An HMAC signature.

SigningContext

A context for multi-step (Init-Update-Finish) HMAC signing.

SigningKey

A key to use for HMAC signing.

VerificationKey

A key to use for HMAC authentication.

Functions

recommended_key_len

Returns the recommended key length for HMAC using the given digest algorithm.

sign

Calculates the HMAC of data using the key key in one step.

verify

Calculates the HMAC of data using the key key, and verifies whether the resultant value equals signature, in one step.

verify_with_own_key

Calculates the HMAC of data using the signing key key, and verifies whether the resultant value equals signature, in one step.