Skip to main content

http-signature-server CircleCI Test Coverage

HTTP server agnostic Python implementation of the server side of the IETF draft "Signing HTTP Messages", with no dependencies other than the Python standard library, although cryptography would typically be used in client code to verify signatures using a public key.

See http-signature-client for a compatible client-side implementation.

Installation

pip install http-signature-server

Usage

from http_signature_server import verify

def verify(key_id, signature, signature_input):
    # If the key_id is not found, return None
    # If the key_id is found and the signature verifies the input, return True
    # If the key_is is found and the signature does not verify the input, return False

error, (key_id, verified_headers) = verify_headers(verify, max_skew, method, path, headers)

if error is not None:
    # Return error or raise exception as needed

Recipe: Verify using Ed25519 public key

from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.serialization import load_pem_public_key

public_key = \
    b'-----BEGIN PUBLIC KEY-----\n' \
    b'MCowBQYDK2VwAyEAe9+zIz+CH9E++J0qiE6aS657qzxsNWIEf2BZcUAQF94=\n' \
    b'-----END PUBLIC KEY-----\n'
public_key = load_pem_public_key(public_key, backend=default_backend())

def verify(key_id, signature, signature_input):
    # Could use the supplied key_id to lookup the public key
    try:
        public_key.verify(signature, signature_input)
    except InvalidSignature:
        return False
    return True

# method, path, and headers would be taken from the incoming HTTP request
error, (key_id, verified_headers) = verify_headers(verify, 10, method, path, headers)

Recipe: Create an Ed25519 public/private key pair

from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives.serialization import Encoding, NoEncryption, PrivateFormat, PublicFormat

private_key = Ed25519PrivateKey.generate()
print(private_key.private_bytes(encoding=Encoding.PEM, format=PrivateFormat.PKCS8, encryption_algorithm=NoEncryption()))
print(private_key.public_key().public_bytes(encoding=Encoding.PEM, format=PublicFormat.SubjectPublicKeyInfo))

API

Parameters

  • verify - A callable taking a str key_id and bytes signature and signature_input. It must return True if key_id is known and signature/signature_input is verified, for example by a corresponding public key; return False if key_id is known but the signature/signature_input is not verified; return None otherwise.

  • max_skew - A maximum integer number of seconds difference from the time an incoming signature claimed to be constructed, and the current time.

  • method - The HTTP method of the request, such as GET or POST.

  • path - The full path of the request, including any query string.

  • headers - A tuple of (key, value) pairs of HTTP headers to attempt to verify.

Returns

A tuple error, (key_id, verified_headers).

  • error - If the request is verified, None. Otherwise a str containing a short reason in English as to why verification failed.

  • key_id - If the request is verified, the keyId from the incoming request. Otherwise, None.

  • verified_headers - If the request is verified, the (key, value) HTTP header pairs that were verified by the signature; this will be a sub-tuple of the headers parameter. Otherwise, None.

What's implemented

A deliberate subset of the signature algorithm is implemented/enforced:

  • the (request-target) pseudo-header is required and verified;
  • the created parameter is required, and the corresponding (created) pseudo-header must be signed;
  • the headers parameter is required;
  • the expires parameter, if sent, must not correspond to a signed (expires) pseudo-header;
  • the algorithm parameter is ignored if sent.

There are a few places where the implementation is technically, and deliberately, non-conforming.

  • The (created) pseudo-header: if this is in the future from the server's point of view, even 1 second, according to the spec verification should fail. Instead, there is a configurable maximum time skew that applies to the future as well as the past.

  • The expires parameter: if this is sent and in the past from the server's point of view, according to the spec verification should fail.

  • The algorithm parameter: if it's sent but does not match what the server expects, according to the spec verification should fail.

It is assumed that the (created) and (request-target) pseudo-headers were prepended to the list of real HTTP headers before canonicalisation at the client. This fact only makes a difference in the edge case of real HTTP headers called (created) or (request-target).

Metadata

Release files for http-signature-server 0.0.12

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

Source distribution (sdist)

Source distribution for http-signature-server 0.0.12
File Size Uploaded
http-signature-server-0.0.12.tar.gz 4.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for http-signature-server 0.0.12
File Interpreter ABI Platform
http_signature_server-0.0.12-py3-none-any.whl Python 3 none any Details

Total release size: 10.2 kB

Release files / http-signature-server-0.0.12.tar.gz

Download URL http-signature-server-0.0.12.tar.gz
Size 4.6 kB
Tags Source
SHA-256 checksum
How to use checksums
21fd49645adee33337dbc8d33e4220c29c739e7db33e990cbe3fbfb7ac5161ac
BLAKE2b-256 checksum
How to use checksums
fe157412aa1044973d3aee3174d47149e0e98a5d56504525455eedff00be7b8c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.1.1 pkginfo/1.4.2 requests/2.20.1 setuptools/47.1.1 requests-toolbelt/0.8.0 tqdm/4.28.1 CPython/3.7.1

Release files / http_signature_server-0.0.12-py3-none-any.whl

Download URL http_signature_server-0.0.12-py3-none-any.whl
Size 5.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c661caa0f13f2558a6ecdd5274f922e67c1d48a45ebeb18203789afffe73a86c
BLAKE2b-256 checksum
How to use checksums
e9387f4f8adb6fe1a8f33020bf808d584f32a68e4243e1c21a713c270f355531
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.1.1 pkginfo/1.4.2 requests/2.20.1 setuptools/47.1.1 requests-toolbelt/0.8.0 tqdm/4.28.1 CPython/3.7.1

Release history Release notifications | RSS feed

This release

0.0.12 This release

2 release files

0.0.11

2 release files

0.0.10

2 release files

0.0.9

2 release files

0.0.8

2 release files

0.0.7

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

0.0.0

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