{"id":4042,"library":"http-message-signatures","title":"HTTP Message Signatures","description":"An implementation of the IETF HTTP Message Signatures draft standard, providing tools to sign and verify HTTP messages using various cryptographic algorithms. The current stable version is 2.0.1, with a moderate release cadence driven by specification updates and bug fixes.","status":"active","version":"2.0.1","language":"en","source_language":"en","source_url":"https://github.com/pyauth/http-message-signatures","tags":["http","security","signatures","ietf","cryptography","authentication"],"install":[{"cmd":"pip install http-message-signatures","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Provides cryptographic primitives for signing and verification.","package":"cryptography"},{"reason":"Used for advanced type hints, ensuring compatibility across Python versions.","package":"typing_extensions"},{"reason":"Handles Structured Field Values parsing and serialization as required by the spec.","package":"http_sfv"}],"imports":[{"symbol":"HTTPSignatureKeySigner","correct":"from http_message_signatures import HTTPSignatureKeySigner"},{"symbol":"HTTPSignatureKeyVerifier","correct":"from http_message_signatures import HTTPSignatureKeyVerifier"},{"note":"A higher-level abstraction for managing multiple signatures.","symbol":"HTTPMessageSignatures","correct":"from http_message_signatures import HTTPMessageSignatures"},{"note":"Contains predefined signing algorithms like EDDSA_25519_SHA512, RSA_V1_5_SHA256.","symbol":"algorithms","correct":"from http_message_signatures import algorithms"}],"quickstart":{"code":"import requests\nfrom http_message_signatures import HTTPSignatureKeySigner, HTTPSignatureKeyVerifier, algorithms\nfrom cryptography.hazmat.primitives.asymmetric import rsa\nfrom cryptography.hazmat.primitives import serialization\n\n# 1. Generate a dummy RSA key pair (for demonstration)\nprivate_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)\npublic_key = private_key.public_key()\n\n# Serialize keys for signer/verifier\nprivate_jwk = private_key.private_bytes(\n    encoding=serialization.Encoding.PEM,\n    format=serialization.PrivateFormat.PKCS8,\n    encryption_algorithm=serialization.NoEncryption()\n).decode()\n\npublic_jwk = public_key.public_bytes(\n    encoding=serialization.Encoding.PEM,\n    format=serialization.PublicFormat.SubjectPublicKeyInfo\n).decode()\n\nkey_id = \"test-key\"\n\n# 2. Prepare an HTTP request\nrequest = requests.Request(\n    method=\"POST\",\n    url=\"https://example.com/data\",\n    headers={\n        \"Host\": \"example.com\",\n        \"Content-Type\": \"application/json\",\n        \"Date\": \"Tue, 20 Apr 2021 02:07:55 GMT\"\n    },\n    data='{\"message\": \"hello world\"}'\n)\n\n# 3. Sign the request\nsigner = HTTPSignatureKeySigner(\n    key_id=key_id,\n    private_key=private_jwk,\n    algorithm=algorithms.RSA_V1_5_SHA256\n)\nsigned_request = signer.sign(request)\n\nprint(\"--- Signed Request Headers ---\")\nfor k, v in signed_request.headers.items():\n    print(f\"{k}: {v}\")\n\n# 4. Verify the signed request (simulate receiving the request)\nverifier = HTTPSignatureKeyVerifier(\n    key_id=key_id,\n    public_key=public_jwk,\n    algorithm=algorithms.RSA_V1_5_SHA256\n)\n\n# Create a dummy requests.Response object for verification\n# In a real scenario, this would be the actual received request\ndummy_received_request = requests.Request(\n    method=signed_request.method,\n    url=signed_request.url,\n    headers=signed_request.headers,\n    data=signed_request.data\n)\n\ntry:\n    is_valid = verifier.verify(dummy_received_request)\n    print(f\"\\nSignature is valid: {is_valid}\")\nexcept Exception as e:\n    print(f\"\\nSignature verification failed: {e}\")","lang":"python","description":"This quickstart demonstrates how to sign and verify an HTTP request using `http-message-signatures`. It involves generating a temporary RSA key pair, creating a `requests.Request` object, signing it with `HTTPSignatureKeySigner`, and then verifying the resulting message with `HTTPSignatureKeyVerifier`. This example requires `requests` and `cryptography`."},"warnings":[{"fix":"Upgrade your Python environment to 3.10 or newer. If you must use older Python versions, pin http-message-signatures to `<2.0.0`.","message":"Python 3.8 and 3.9 are no longer supported. Version 2.0.0 dropped support for Python 3.9, and 2.0.1 explicitly removed metadata for Python 3.8/3.9. Projects must use Python 3.10 or newer.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Review the documentation for `HTTPMessageSignatures` and adapt your signing/verification logic to correctly handle potentially multiple 'Signature' headers and their associated parameters.","message":"Version 2.0.0 introduced support for multiple signatures on a single message. While this enhances functionality, it may involve changes to how signatures are added and retrieved from messages, potentially breaking existing code that assumed a single 'Signature' header.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Upgrade to version 1.0.1 or newer to ensure correct 'request-target' calculation. If verifying old signatures with new verifiers (or vice versa), be aware of this potential discrepancy.","message":"Versions prior to 1.0.1 had a bug in the `get_request_target` method, which could lead to an incorrect 'request-target' component in the signature (e.g., an extra '?'). This can cause signature mismatches between signers and verifiers on different versions.","severity":"gotcha","affected_versions":"<1.0.1"},{"fix":"Ensure your `HTTPMessageVerifier` instances are configured with an appropriate `max_clock_skew` value to mitigate replay attacks. Upgrade to 0.5.0 or newer to use this feature directly.","message":"The `max_clock_skew` parameter was added to `HTTPMessageVerifier` in version 0.5.0. Without this parameter, the verifier does not automatically account for clock differences between the signer and verifier, potentially making systems vulnerable to replay attacks if not handled externally.","severity":"gotcha","affected_versions":"<0.5.0"},{"fix":"Always use strong, recommended algorithms (e.g., EDDSA_25519_SHA512, RSA-PSS with SHA-512). Store private keys securely, rotate them regularly, and avoid hardcoding them. Follow industry best practices for key lifecycle management.","message":"Mismanagement of cryptographic keys (e.g., using weak algorithms, exposing private keys, or reusing keys across different contexts) is a common security vulnerability. While the library provides the signing mechanisms, key management is left to the user.","severity":"gotcha","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}