Expand description
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 SigningKey
s;
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
An HMAC signature.
A context for multi-step (Init-Update-Finish) HMAC signing.
A key to use for HMAC signing.
A key to use for HMAC authentication.
Functions
Returns the recommended key length for HMAC using the given digest algorithm.
Calculates the HMAC of data
using the key key
in one step.
Calculates the HMAC of data
using the key key
, and verifies whether the
resultant value equals signature
, in one step.
Calculates the HMAC of data
using the signing key key
, and verifies
whether the resultant value equals signature
, in one step.