A python package that creates and verifies HMAC signatures
Project description
HMAC Authentication (easy-hmac)
A pure python package with no dependencies to easily handle the generation and verification of HMAC signatures.
Installation
This package is hosted at https://pypi.org/project/easy-hmac/
User
If you don't need to customise this package, just install the package from here.
Ie. pip install easy-hmac
Developer
- Clone this repository
- Build the package in your local environment.
pipenv shell
pipenv install build
python -m build easy-hmac
- Install the easy-hmac package in editing mode by running:
pip install -e easy-hmac
- If you want to make sure everything went well, try running the tests from test_easy-hmac
python easy_hmac/test/test_easy-hmac.py
Usage
easy-hmac
provides two helper functions for HMAC authentication:
generate_hmac_sha256
- generates a SHA256 HMAC from two strings (a secret key and a http message)verify_hmac
- given an HMAC and a message, verifies if the HMAC generated by the message is equal to the one passed as argument
Step 1
Import the package.
python import datetime from easy_hmac import core import hmac import hashlib from base64 import b64encode from typing import Dict, Any
Step 2
Create some vars we can use to generate and verify the HMAC.
# fake identifier used to retrieve the secret from a db.
secret = "79721503-d1ef-46b7-b4ca-fec39ece902f"
body = '{"event": "lifecycle_updated", "payload": {"uuid": "cb8c79cd-8d79-4698-90a2-662eeab8da98", "timestamp": "2021-12-10T00:16:08.048401Z", "status": "PROCESSING"}}'
method = "POST"
timestamp = datetime.datetime.now(datetime.UTC).strftime("%a, %d %b %Y %H:%M:%S GMT")
path = "/api/v1/my/path"
# vars required for verifying the HMAC.
# This step is a little long because we need to fake some parameters we'd usually already have.
identifier = "2e42a19593f047e080285e49864b0fb6"
hash = hashlib.md5(body.encode())
content_type = "application/json"
content_md5 = b64encode(hash.digest()).decode('utf-8')
message = "\n".join([method, content_md5, content_type, timestamp, path])
signature = hmac.new(bytes(secret, "latin-1"), bytes(message, "latin-1"), digestmod=hashlib.sha256)
hmac_base64 = b64encode(signature.digest()).decode("utf-8")
headers = {
"Date": timestamp,
"Content-MD5": content_md5,
"Content-Type": content_type,
"Authorization": "HMAC {}:{}".format(identifier, hmac_base64),
}
request = {"method": method, "body": body, "path": path, "headers": headers}
Step 3
Create and verify the signature.
result_digest = core.generate_hmac_sha256(secret, method, body, path, timestamp)
actual_signature = b64encode(result_digest).decode()
expected_signature = "d8laojz+oDCPizTL1a401mHq5IpR1A9f9QK3+RQ/6hA="
core.verify_hmac(secret, hmac_base64, headers["Content-MD5"], body.encode(), headers["Date"], headers["Content-Type"], path, method)
``
You can raise an exception that the request has expired by changing the timestamp to;
`timestamp = "Fri, 10 Dec 2021 00:16:57 GMT"`
and then rerunning the second set of vars above to generate an incoming request that is too old and verifying
the signature again.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file easy-hmac-0.0.6.tar.gz
.
File metadata
- Download URL: easy-hmac-0.0.6.tar.gz
- Upload date:
- Size: 9.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.9.18
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 7a658bf941e4f20483eb7843b4e4efd67cab67f2b8f41f3b2f95303dc30e4e99 |
|
MD5 | 4706dee239841d8b907269fcb41306d8 |
|
BLAKE2b-256 | fff238c701e055b7300a1f4f8c95259deb6709d33445290950ae3f93f389f971 |
File details
Details for the file easy_hmac-0.0.6-py3-none-any.whl
.
File metadata
- Download URL: easy_hmac-0.0.6-py3-none-any.whl
- Upload date:
- Size: 7.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.9.18
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 186b38a4f222c636c01f0f738619a0f7a1e16a5dbef245aecd4504143e3956bc |
|
MD5 | c4fcc976ffed286b9e0291ac7e2bab52 |
|
BLAKE2b-256 | 53a83fddfe05b34cf039c9a23e4030ec1679df067776132c7c823b64b81817ec |