Implementation of the client side of the IETF draft "Signing HTTP Messages"
Project description
http-signature-client
Utility function with an HTTP client agnostic Python implementation of the client side of the IETF draft "Signing HTTP Messages". No dependencies other than the standard library, but cryptography would typically be required in client code to load a private key.
Usage
from http_signature_client import sign_headers
signed_headers = sign_headers(key_id, sign, method, path, headers_to_sign)
Recipe: Python requests with PEM-encoded private key and SHA-512 body digest
from base64 import b64encode
import hashlib
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.serialization import load_pem_private_key
import requests
import urllib3
from http_signature_client import sign_headers
class HttpSignatureWithBodyDigest(request.auth.AuthBase):
def __init__(self, key_id, pem_private_key):
self.key_id = key_id
self.private_key = load_pem_private_key(
pem_private_key, password=None, backend=default_backend())
def __call__(self, r):
body_sha512 = b64encode(hashlib.sha512(r.body).digest()).decode('ascii')
headers_to_sign = tuple(r.headers.items()) + (('digest', f'SHA512={body_sha512}'),)
parsed_url = urllib3.util.url.parse_url(r.path_url)
path = parsed_url.path + (f'?{parsed_url.query}' if parsed_url.query else '')
r.headers = dict(sign_headers(
self.key_id, self.private_key.sign, r.method, path, headers_to_sign))
return r
# In real cases, take credentials from environment variables/secret store
key_id = 'my-key'
pem_private_key =\
b'-----BEGIN PRIVATE KEY-----\n' \
b'MC4CAQAwBQYDK2VwBCIEINQG5lNt1bE8TZa68mV/WZdpqsXaOXBHvgPQGm5CcjHp\n' \
b'-----END PRIVATE KEY-----\n'
response = requests.post('http://mydomain.test/path', data=b'The bytes',
auth=HttpSignature(key_id, pem_private_key))
What's implemented
A deliberate subset of the signature algorithm is implemented:
- the
request-target
pseudo-header is signed [to allow the server to verify the method and path] - the
created
pseudo-header is signed [to allow the server to decide to reject if the skew is too large] - the
headers
parameter is sent [to allow the server to verify headers and pseudo-headers] - the
expires
parameter is not sent [the server can decide this using the created parameter]; - the
algorithm
parameter is not sent [it should not be used by the server to choose the algorithm].
Note not all headers passed as the headers_to_sign
parameter are signed by default: common hop-by-hop headers are ignored, since they typically won't make it to the target server unchanged. To customise this list of ignored headers, override the headers_to_ignore
parameter.
Project details
Release history Release notifications | RSS feed
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
Hashes for http-signature-client-0.0.6.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | b0b067519d1e7977a641ef7d555cb7e9525020138cd79ded474c0898c419ef9a |
|
MD5 | 6b401531f249f41d3691057d49817276 |
|
BLAKE2b-256 | 392623047091c65f3a2c0e190950d2b3c414dbfcbe875ab7b5436d9b5d087e87 |
Hashes for http_signature_client-0.0.6-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 45d921c1c40da968b1ce72bd33153a0adff614fa78073553681cbb728ab057e0 |
|
MD5 | b890a867fc88a152852115348521931f |
|
BLAKE2b-256 | f77b636e9837642bedf1a2b467f94443e2acffce7d6414ef42f9acd88cb494ed |