Skip to main content

easy-hmac

PyPI Python License: MIT

A pure Python package with zero dependencies to generate and verify HMAC-SHA256 signatures for HTTP request authentication.

Installation

pip install easy-hmac

Quick Start

Generate a signature

import datetime
from base64 import b64encode

from easy_hmac import generate_hmac_sha256

secret = "my-secret-key"
body = '{"event": "updated", "status": "PROCESSING"}'
method = "POST"
path = "/api/v1/webhook"
timestamp = datetime.datetime.now(datetime.UTC).strftime("%a, %d %b %Y %H:%M:%S GMT")

digest = generate_hmac_sha256(secret, method, body, path, timestamp)
signature = b64encode(digest).decode()

Verify a signature

from easy_hmac import verify_hmac, AuthenticationFailed

try:
    verify_hmac(
        secret=secret,
        hmac_base64=signature,
        md5_body=content_md5,
        raw_body=body.encode(),
        timestamp=timestamp,
        content_type="application/json",
        path=path,
        request_method=method,
    )
except AuthenticationFailed:
    # Signature invalid, body tampered, or timestamp expired (>15 min)
    pass

API

generate_hmac_sha256(secret, method, body, path, timestamp)

Generates an HMAC-SHA256 digest from HTTP request components.

Parameter Type Description
secret str The shared secret key
method str HTTP method (e.g. "POST")
body str The request body
path str The request path (e.g. "/api/v1/webhook")
timestamp str GMT timestamp formatted as "%a, %d %b %Y %H:%M:%S GMT"

Returns: bytes — the raw HMAC digest.

verify_hmac(secret, hmac_base64, md5_body, raw_body, timestamp, content_type, path, request_method)

Verifies an incoming HMAC signature against the request components. Checks the body integrity via MD5 hash and rejects requests older than 15 minutes.

Parameter Type Description
secret str The shared secret key
hmac_base64 str The base64-encoded HMAC from the request's Authorization header
md5_body str The base64-encoded MD5 hash from the Content-MD5 header
raw_body bytes The raw request body
timestamp str The Date header value
content_type str The Content-Type header value
path str The request path
request_method str The HTTP method

Returns: True if verification succeeds.

Raises: AuthenticationFailed if the signature is invalid, the body was tampered, the timestamp is malformed, or the request is older than 15 minutes.

Exceptions

AuthenticationFailed

Raised by verify_hmac when verification fails. Subclass of Exception.

Message Format

Both functions construct the HMAC message by joining components with newlines:

HTTP_METHOD\nCONTENT_MD5\nCONTENT_TYPE\nTIMESTAMP\nPATH

This follows a common pattern for REST API HMAC authentication where the content MD5 ensures body integrity and the timestamp prevents replay attacks.

Development

# Clone and set up
uv sync

# Run tests
uv run pytest

# Build
uv build

License

MIT

Release files for easy-hmac 1.2.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for easy-hmac 1.2.2
File Size Uploaded
easy_hmac-1.2.2.tar.gz 84.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for easy-hmac 1.2.2
File Interpreter ABI Platform
easy_hmac-1.2.2-py3-none-any.whl Python 3 none any Details

Total release size: 91.0 kB

Release files / easy_hmac-1.2.2.tar.gz

Download URL easy_hmac-1.2.2.tar.gz
Size 84.5 kB
Tags Source
SHA-256 checksum
How to use checksums
27e25154efd73c8e1c15c75dadff285d8d2a1bbdc1ae11d0b4c38b8faea19846
BLAKE2b-256 checksum
How to use checksums
21c34d8e15a7ac6ee2a4dbbc4a60332c17b87ed9e8e7b2c8142adb066e065bf1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / easy_hmac-1.2.2-py3-none-any.whl

Download URL easy_hmac-1.2.2-py3-none-any.whl
Size 6.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
011790d89986b5605b865d68e7b8b240688943167ac558371278e8a71349db70
BLAKE2b-256 checksum
How to use checksums
779f31dd585a77335805dcae1e80d5b52e342098f6b110becd46a5afd0c63f02
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

1.2.2 This release

2 release files

1.2.1

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page