{"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":"python","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":[{"wrong":"from http_message_signatures import HTTPSignatureKeySigner","symbol":"HTTPSignatureKeySigner","correct":"from http_message_signatures import HTTPSignatureKeySigner"}],"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,"search_vec":"'2.0.1':31 'algorithm':25 'authent':49 'bug':42 'cadenc':36 'cryptograph':24 'cryptographi':48 'current':27 'draft':12 'driven':37 'fix':43 'http':1,9,20,44 'ietf':8,47 'implement':5 'messag':2,10,21 'moder':34 'provid':14 'releas':35 'secur':45 'sign':17 'signatur':3,11,46 'specif':39 'stabl':28 'standard':13 'tool':15 'updat':40 'use':22 'various':23 'verifi':19 'version':29","created_at":"2026-04-12T03:38:30.828348+00:00","updated_at":"2026-04-16T15:37:05.542488+00:00","problems":{"verify_error":"Traceback (most recent call last):\n  File \"<string>\", line 1, in <module>\n  File \"/tmp/tmpu_h1hmgo/venv/lib/python3.12/site-packages/http_message_signatures/__init__.py\", line 4, in <module>\n    from .resolvers import HTTPSignatureComponentResolver  # noqa:F401\n    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"},"ecosystem":"pypi","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"2.0.1","cli_name":"","cli_version":null,"type":"library","homepage":null,"github":"https://github.com/pyauth/http-message-signatures","docs":null,"changelog":null,"pypi":"https://pypi.org/project/http-message-signatures/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["http-networking","auth-security"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-07-03","last_verified":"2026-08-29","next_check":"2026-07-10","install_tag":null}}