ring

Module hmac

Source
Expand description

HMAC is specified in RFC 2104.

After a Key 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, Context should be used.

§Examples:

§Signing a value and verifying it wasn’t tampered with

use ring::{hmac, rand};

let rng = rand::SystemRandom::new();
let key = hmac::Key::generate(hmac::HMAC_SHA256, &rng)?;

let msg = "hello, world";

let tag = 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(&key, msg.as_bytes(), tag.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 rng = rand::SystemRandom::new();
let key_value: [u8; digest::SHA256_OUTPUT_LEN] = rand::generate(&rng)?.expose();

let s_key = hmac::Key::new(hmac::HMAC_SHA256, key_value.as_ref());
let tag = 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::Key::new(hmac::HMAC_SHA256, key_value.as_ref());
hmac::verify(&v_key, msg.as_bytes(), tag.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 rng = rand::SystemRandom::new();
let mut key_value: [u8; digest::SHA384_OUTPUT_LEN] = rand::generate(&rng)?.expose();

let s_key = hmac::Key::new(hmac::HMAC_SHA384, key_value.as_ref());
let mut s_ctx = hmac::Context::with_key(&s_key);
for part in &parts {
    s_ctx.update(part.as_bytes());
}
let tag = s_ctx.sign();

// The receiver (somehow!) knows the key value, and uses it to verify the
// integrity of the message.
let v_key = hmac::Key::new(hmac::HMAC_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(), tag.as_ref())?;

Structs§

  • An HMAC algorithm.
  • A context for multi-step (Init-Update-Finish) HMAC signing.
  • A key to use for HMAC signing.
  • An HMAC tag.

Statics§

Functions§

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