digest.hmac_sha1_base64

STRINGdigest.hmac_sha1_base64STRINGkeySTRINGs

Available inall subroutines.

Returns the HMAC-SHA1 of message using key, encoded as a Base64 string.

Parameters

ParameterTypeDescription
keySTRINGThe secret key for HMAC computation
messageSTRINGThe message to authenticate

The key is used directly as the HMAC key. For keys longer than 64 bytes (the SHA-1 block size), the key is first hashed with SHA-1 before use, as specified in RFC 2104.

Return value

Returns a 28-character Base64-encoded string representing the 160-bit (20-byte) HMAC, using standard Base64 encoding (RFC 4648 Section 4) with padding.

Example output: uEsAIHcVJkam2pIc9YEhcFFQqWc=

If key is empty or not set, the function returns an empty string (not set).

Security notice

While HMAC-SHA1 is still believed to be secure, SHA-1 has known cryptographic weaknesses and is considered deprecated for new applications. For new code, use digest.hmac_sha256_base64 instead.

Use HMAC-SHA1 only when required for compatibility with existing systems that mandate it.

Base64 encoding

This function uses standard Base64 encoding as defined in RFC 4648 Section 4:

PropertyValue
AlphabetA-Za-z0-9+/
Padding= (always used)

Examples

Basic usage

declare local var.hmac STRING;
set var.hmac = digest.hmac_sha1_base64("secret-key", "hello world");
# Result: uEsAIHcVJkam2pIc9YEhcFFQqWc=

To verify this output using OpenSSL:

$ echo -n "hello world" | openssl dgst -sha1 -hmac "secret-key" -binary | openssl base64
uEsAIHcVJkam2pIc9YEhcFFQqWc=

OAuth 1.0 signature with Base64

OAuth 1.0 signatures are typically transmitted as Base64:

sub vcl_recv {
declare local var.base_string STRING;
declare local var.signing_key STRING;
declare local var.signature STRING;
declare local var.signature_encoded STRING;
set var.base_string = req.http.X-OAuth-Base-String;
set var.signing_key = table.lookup(oauth_secrets, "consumer_secret") + "&"
+ table.lookup(oauth_secrets, "token_secret");
set var.signature = digest.hmac_sha1_base64(var.signing_key, var.base_string);
# URL-encode the Base64 signature for inclusion in OAuth header
set var.signature_encoded = urlencode(var.signature);
}

Verifying legacy webhook signatures

Some webhook providers send Base64-encoded HMAC-SHA1 signatures:

sub vcl_recv {
declare local var.expected STRING;
declare local var.secret STRING;
set var.secret = table.lookup(webhook_secrets, "legacy-service");
if (var.secret == "") {
error 500 "Webhook secret not configured";
}
set var.expected = digest.hmac_sha1_base64(var.secret, req.body);
if (!digest.secure_is_equal(var.expected, req.http.X-Signature)) {
error 401 "Invalid signature";
}
}

Security considerations

Prefer SHA-256 for new applications

# Recommended for new code
set var.signature = digest.hmac_sha256_base64(var.key, var.message);

Constant-time comparison

When comparing HMAC values for authentication, always use digest.secure_is_equal to prevent timing attacks. String comparison with == leaks information about which bytes matched, potentially allowing an attacker to forge valid authentication tags:

if (!digest.secure_is_equal(var.expected, var.actual)) {
error 401 "Invalid signature";
}