Package: http-message-signatures
http-message-signaturesis an implementation of the IETFRFC 9421 HTTP Message Signaturesdraft standard in
Python.Installationpip3 install http-message-signaturesSynopsisfromhttp_message_signaturesimportHTTPMessageSigner,HTTPMessageVerifier,HTTPSignatureKeyResolver,algorithmsimportrequests,base64,hashlib,http_sfvclassMyHTTPSignatureKeyResolver(HTTPSignatureKeyResolver):keys={"my-key":b"top-secret-key"}defresolve_public_key(self,key_id:str):returnself.keys[key_id]defresolve_private_key(self,key_id:str):returnself.keys[key_id]request=requests.Request('POST','https://example.com/foo?param=Value&Pet=dog',json={"hello":"world"})request=request.prepare()request.headers["Content-Digest"]=str(http_sfv.Dictionary({"sha-256":hashlib.sha256(request.body).digest()}))signer=HTTPMessageSigner(signature_algorithm=algorithms.HMAC_SHA256,key_resolver=MyHTTPSignatureKeyResolver())signer.sign(request,key_id="my-key",covered_component_ids=("@method","@authority","@target-uri","content-digest"))verifier=HTTPMessageVerifier(signature_algorithm=algorithms.HMAC_SHA256,key_resolver=MyHTTPSignatureKeyResolver())verifier.verify(request)Note that verifying the body content-digest is outside the scope of this package’s functionality, so it remains the
caller’s responsibility. Therequests-http-signaturelibrary
builds upon this package to provide integrated signing and validation of the request body.See what is signedIt is important to understand and follow the best practice rule of “See what is signed” when verifying HTTP message
signatures. The gist of this rule is: if your application neglects to verify that the information it trusts is
what was actually signed, the attacker can supply a valid signature but point you to malicious data that wasn’t signed
by that signature. Failure to follow this rule can lead to vulnerability against signature wrapping and substitution
attacks.In http-message-signatures, you can ensure that the information signed is what you expect to be signed by only trusting the
data returned by theverify()method:verify_results = verifier.verify(request)This returns a list ofVerifyResults, which arenamedtuples with the following attributes:label (str): The label for the signaturealgorithm: (same as signature_algorithm above)covered_components: A mapping of component names to their values, as covered by the signatureparameters: A mapping of signature parameters to their values, as covered by the signaturebody: AlwaysNone(therequests-http-signaturepackage
implements returning the body upon successful digest validation).Given an HTTP request can potentially have multiple signatures theverify()method returns a list ofVerifyResults.
However, the implementation currently supports just one signature, so the returned list currently contains just one element.
If more signatures are found in the request thenInvalidSignatureis raised.Additionally, theverify()method raisesHTTPMessageSignaturesExceptionor an exception derived from this class in
case an error occurs (unable to load PEM key, unsupported algorithm specified in signature input, signature doesn’t match
digest etc.)AuthorsAndrey KislyukLinksProject home page (GitHub)DocumentationPackage distribution (PyPI)Change logIETF HTTP Message Signatures standard trackerOWASP Top TenBugsPlease report bugs, issues, feature requests, etc. onGitHub.LicenseLicensed under the terms of theApache License, Version 2.0.