Reference · Crypto

crypto.hmac

signature
crypto.hmac(str, str) -> str

What it does

The HMAC-SHA256 of a message under a key, as 64 lower-case hex characters: the key first, the message second. Whoever knows the key can make the same tag and check it, and nobody else can; that is how a signed cookie, a webhook's signature or a reset link is checked. Compare a tag that came from outside with crypto.equal, in constant time.

Examples

print(crypto.hmac("key", "The quick brown fox jumps over the lazy dog"))let tag = crypto.hmac("secret", "user=7&expires=1900000000")print(tag)print(crypto.equal(tag, crypto.hmac("secret", "user=7&expires=1900000000")))
output
f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd808e8db197ec52faefa8b59f1619591cd5a7897bf1899f12733d9536315804fbftrue

Edge cases

print(crypto.hmac("a", "b") == crypto.hmac("b", "a"))print(crypto.hmac("", ""))print(len(crypto.hmac(repeat("k", 1000), "m")))print(crypto.hmac("secret", "user=7") == crypto.hmac("secret", "user=8"))
output
falseb613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad64false

Errors

A key or a message that is not a string is a runtime error, not an error value; leaving the message out is one too.

this one fails
print(crypto.hmac("key"))
output
line 1: `crypto.hmac` expects a str as argument 2, got nothing
this one fails
print(crypto.hmac(123, "message"))
output
line 1: `crypto.hmac` expects a str as argument 1, got int

Chaining

In a pipeline the piped value becomes the first argument, the key: msg | crypto.hmac(key) signs key under msg, which is not what is wanted. Write the call out, or pipe the key on purpose.

print(("message" | crypto.hmac("key")) == crypto.hmac("message", "key"))print(crypto.hmac(env("SIGNING_KEY") ?? "dev", "order:42") | slice(0, 16))
output
truedcf53914470ce8a9

See also

crypto.sha256, crypto.equal, crypto.token, env

Thread
6Useful? Like it, or add to its thread below.

Thread 0 posts

On crypto.hmac(): questions, tips, corrections, and code that uses it.

No posts yet. The first one opens the thread.

    Edit this page on GitHub · every example's output was made by running it (tools/refcheck.mjs) · questions on Discord or r/quillo