For Development HEAD DRAFTSearch (procedure/syntax/module):

12.45 rfc.hmac - HMAC keyed-hashing

Module: rfc.hmac

This module implements HMAC algorithm, Keyed-hashing for message authentication, defined in RFC 2104.

For simple batched keyed hashing, you can use high-level API hmac-digest and hmac-digest-string. Or you can create <hmac> object and update its state as the data coming in.

Following is a typical way to digest a given string.

(use rfc.sha)  ; import desired digest algorithm
(use rfc.hmac)

(hmac-message <sha256> "secret-key" "payload")
 ⇒ #u8(16 170 46 28 37 56 70 79 247 95 6 71 39 30 59 167 70 188 163
    252 222 175 50 44 88 27 245 133 30 140 221 183)

(hmac-message-to 'hex <sha256> "secret-key" "payload")
 ⇒ "10aa2e1c2538464ff75f0647271e3ba746bca3fcdeaf322c581bf5851e8cddb7"

High-level API

Function: hmac-to target algorithm key

{rfc.hmac} Read input data from the current input port, and compute HMAC digest with a hash algorithm hash-class and a key key.

The result is returned as an instance of class target, which can be <u8vector> or <string>. Some symbols is also allowed to specify encoding: base64, base64url, base64url-nopad, base32, base32hex, base16, and hex. See util.digest - Message digester framework for the details of those encodings.

The hash-class argument must be a class implementing <message-digest-algorithm>, such as <sha256> of rfc.sha (see rfc.sha - SHA message digest).

The key key may be a string or a u8vector.

Function: hmac-message-to target hash-class key message

{rfc.hmac} Returns an HMAC digest of message, computed with a hash algorithm hash-class, with a key key.

The hash-class argument must be a class inheriting <message-digest-algorithm>, e.g. <sha256> class from rfc.sha (see rfc.sha - SHA message digest).

You can pass both a stirng and a u8vector to key/message.

The target can be a class in which the result is returned, either <u8vector> or <string>, or a symbol specifying the encoding: base64, base64url, base64url-nopad, base32, base32hex, base16, and hex. See util.digest - Message digester framework for the details of those encodings.

Function: hmac-message hash-class key message

{rfc.hmac} A shortcut of (hmac-message-to <u8vector> hash-class key message).

(hmac-message <sha256> "secret" "Aloha, honua")
 ⇒ #u8(78 232 135 13 246 139 36 242 133 33 99 185 4 249 244
    22 243 46 120 130 192 235 60 187 172 180 223 169 179 247 186 185)
Function: hmac-verify hash-class digest key message

{rfc.hmac} Verify message by comparing its digest with the given digest. Functionally it is (equal? digest (hmac-message hash-class key message)), but the digests are compared in a way that can avoid timing attack.

Hash-class is a class inherits <message-digest-algorithm> such as <sha256>. Digest must be a u8vector. Either a string or a u8vector is allowed for each of key and message.

Returns #t if digest is valid digest for the message, #f if not.

(hmac-verify <sha256>
             '#u8(78 232 135 13 246 139 36 242 133 33 99 185 4 249 244 22 243 46
                  120 130 192 235 60 187 172 180 223 169 179 247 186 185)
             "secret"
             "Aloha, honua")
 ⇒ #t

Low-level API

Class: <hmac>

{rfc.hmac} Keeps state information of HMAC algorithm. This should not be directly instantiated; use make-hmac below.

Function: make-hmac algorithm key

{rfc.hmac} Creates and returns a new <hmac> object. The algorithm argument is a class inheriting <message-digest-algorithm> to specify digest algorithm, for example, <sha256> (see rfc.sha - SHA message digest, for the details). The key argument is a key, either a string or a u8vector.

When you use high-level APIs such as hmac-message, you don’t need to make an <hmac> object since it is implicitly created. You only need to create it explicitly to use the following streaming update procedures.

Method: hmac-update! (hmac <hmac>) data

{rfc.hmac} Updates the internal state of hmac by data, which must be represented by a (possibly incomplete) string.

Method: hmac-final! (hmac <hmac>) :optional target

{rfc.hmac} Finalizes the internal state of hmac and returns the digest in an instance of target, which must be a <string> or <u8vector> class metaobject, or a symbol to specify encoding. See hmac-to above for the details of target. The default is <string>, for a historical reason.

Once finalized, you can’t call hmac-update! or hmac-final! on hmac.

Deprecated API

The following procedures are deprecated. You can use hmac-to and hmac-message instead.

Function: hmac-digest :key key hasher

{rfc.hmac} Deprecated. Creates an <hmac> object and hash the data stream from the current input port, then returns the hashed result in an incomplete string.

Function: hmac-digest-string string :key key hasher

{rfc.hmac} Deprecated. Creates an <hmac> object and hash the data in string, then returns the hashed result in an incomplete string.



For Development HEAD DRAFTSearch (procedure/syntax/module):
DRAFT