Skip to content

hmac

The Python hmac module implements the Hash-based Message Authentication Code (HMAC) algorithm described in RFC 2104. It combines a secret key with a message and a cryptographic hash function to produce an authentication tag that verifies both the integrity and the authenticity of the data.

Here’s a quick example:

Language: Python
>>> import hmac
>>> import hashlib

>>> secret = b"shared-secret"
>>> message = b"transfer 100 USD to alice"
>>> hmac.new(secret, message, hashlib.sha256).hexdigest()
'a8799a4ac7f268038fe298c315ea9c9ff77391c2db1fa021c51bdf1e763873ba'

Any receiver that knows the same secret key can recompute the tag and confirm that the message has not been altered in transit.

Key Features

  • Implements HMAC on top of any fixed-size hash function provided by hashlib
  • Accepts keys and messages as bytes or bytearray objects
  • Supports one-shot hmac.digest() and incremental hashing through HMAC.update()
  • Provides hmac.compare_digest() for constant-time comparison that resists timing attacks
  • Exposes .digest_size, .block_size, and .name attributes on HMAC objects
  • Allows cloning an HMAC object with .copy() to reuse a common prefix across many computations

Frequently Used Classes and Functions

Object Type Description
hmac.new() Function Creates a new HMAC object from a key, an optional initial message, and a digest algorithm
hmac.digest() Function Computes the HMAC of a key and message in a single optimized call
hmac.compare_digest() Function Compares two digests in constant time to prevent timing attacks
hmac.HMAC Class Represents an HMAC object built incrementally from chunks of data
HMAC.update() Method Feeds additional bytes into the HMAC object
HMAC.digest() Method Returns the current authentication tag as raw bytes
HMAC.hexdigest() Method Returns the current authentication tag as a hexadecimal string
HMAC.copy() Method Returns a clone of the HMAC object, useful for shared prefixes

Examples

Computing a tag in a single call with the hmac.digest() method:

Language: Python
>>> import hmac

>>> secret = b"shared-secret"
>>> message = b"transfer 100 USD to alice"
>>> hmac.digest(secret, message, "sha256").hex()
'a8799a4ac7f268038fe298c315ea9c9ff77391c2db1fa021c51bdf1e763873ba'

Building the tag incrementally when the message arrives in chunks:

Language: Python
>>> import hmac

>>> tag = hmac.new(b"shared-secret", digestmod="sha256")
>>> tag.update(b"transfer 100 USD ")
>>> tag.update(b"to alice")
>>> tag.hexdigest()
'a8799a4ac7f268038fe298c315ea9c9ff77391c2db1fa021c51bdf1e763873ba'

Verifying a tag safely with compare_digest() instead of the equality operator:

Language: Python
>>> import hmac

>>> secret = b"shared-secret"
>>> message = b"transfer 100 USD to alice"
>>> expected = hmac.new(secret, message, "sha256").hexdigest()
>>> hmac.compare_digest(expected, expected)
True
>>> hmac.compare_digest(expected, "0" * len(expected))
False

Inspecting the algorithm metadata on an HMAC object:

Language: Python
>>> import hmac

>>> tag = hmac.new(b"shared-secret", b"hello", "sha256")
>>> tag.name
'hmac-sha256'
>>> tag.digest_size
32
>>> tag.block_size
64

Common Use Cases

The most common tasks for hmac include:

  • Signing and verifying webhook payloads sent between services
  • Protecting session cookies and signed tokens from tampering
  • Authenticating API requests using a shared secret
  • Deriving keys and verifying file integrity in custom protocols
  • Detecting corruption or modification in messages exchanged over untrusted channels

Real-World Example

Consider a service that receives webhook callbacks from a payment provider. Each request includes a signature header computed with a shared secret, and the receiver must confirm that the payload is genuine before acting on it:

Language: Python
>>> import hashlib
>>> import hmac
>>> import json

>>> webhook_secret = b"shhh-this-is-secret"
>>> payload = json.dumps(
...     {"event": "payment.completed", "amount": 4200},
...     separators=(",", ":"),
... ).encode()

>>> signature = hmac.new(webhook_secret, payload, hashlib.sha256).hexdigest()
>>> def verify(payload, signature, secret):
...     expected = hmac.new(secret, payload, hashlib.sha256).hexdigest()
...     return hmac.compare_digest(expected, signature)
...

>>> verify(payload, signature, webhook_secret)
True
>>> verify(payload + b"tampered", signature, webhook_secret)
False

The verification function recomputes the expected tag from the raw bytes of the payload and the shared secret, then compares it against the signature supplied by the sender using compare_digest(). Any modification to the payload, even a single byte, produces a completely different tag and causes verification to fail.

Tutorial

Bytes Objects: Handling Binary Data in Python

In this tutorial, you'll learn about Python's bytes objects, which help you process low-level binary data. You'll explore how to create and manipulate byte sequences in Python and how to convert between bytes and strings. Additionally, you'll practice this knowledge by coding a few fun examples.

intermediate python

For additional information on related topics, take a look at the following resources:


By Leodanis Pozo Ramos • Updated April 23, 2026