2017-08-22 02:02:39 +02:00
|
|
|
requests-http-signature: A Requests auth module for HTTP Signature
|
|
|
|
==================================================================
|
|
|
|
**requests-http-signature** is a `Requests <https://github.com/requests/requests>`_ `authentication plugin
|
|
|
|
<http://docs.python-requests.org/en/master/user/authentication/>`_ (``requests.auth.AuthBase`` subclass) implementing
|
2022-04-10 23:50:12 +02:00
|
|
|
the `IETF HTTP Message Signatures draft RFC <https://datatracker.ietf.org/doc/draft-ietf-httpbis-message-signatures/>`_.
|
2017-08-22 02:02:39 +02:00
|
|
|
|
2017-08-24 16:43:04 +02:00
|
|
|
Installation
|
|
|
|
------------
|
|
|
|
::
|
|
|
|
|
2017-08-29 08:03:51 +02:00
|
|
|
$ pip install requests-http-signature
|
2017-08-24 16:43:04 +02:00
|
|
|
|
|
|
|
Usage
|
|
|
|
-----
|
|
|
|
|
2017-08-22 02:02:39 +02:00
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
import requests
|
2022-04-10 23:50:12 +02:00
|
|
|
from requests_http_signature import HTTPSignatureAuth, algorithms
|
2017-08-29 08:03:51 +02:00
|
|
|
|
2017-08-22 23:51:33 +02:00
|
|
|
preshared_key_id = 'squirrel'
|
2022-04-10 23:50:12 +02:00
|
|
|
preshared_secret = b'monorail_cat'
|
2017-08-22 23:49:25 +02:00
|
|
|
url = 'http://example.com/path'
|
2017-08-22 02:02:39 +02:00
|
|
|
|
2022-04-11 17:48:43 +02:00
|
|
|
auth = HTTPSignatureAuth(key=preshared_secret,
|
|
|
|
key_id=preshared_key_id,
|
|
|
|
signature_algorithm=algorithms.HMAC_SHA256)
|
2022-04-10 23:50:12 +02:00
|
|
|
requests.get(url, auth=auth)
|
|
|
|
|
|
|
|
By default, only the ``Date`` header and the ``@method``, ``@authority``, and ``@target-uri`` derived component
|
|
|
|
identifiers are signed for body-less requests such as GET. The ``Date`` header is set if it is absent. In addition, for
|
|
|
|
requests with bodies (such as POST), the ``Content-Digest`` header is set to the SHA256 of the request body using the
|
|
|
|
format described in the
|
|
|
|
`IETF Digest Fields draft RFC <https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-digest-headers>`_ and signed.
|
|
|
|
To add other headers to the signature, pass an array of header names in the ``covered_component_ids`` keyword argument.
|
2022-04-12 21:53:19 +02:00
|
|
|
See the `API documentation <https://pyauth.github.io/requests-http-signature/#id3>`_ for the full list of options and
|
2022-04-11 19:15:47 +02:00
|
|
|
details.
|
2017-08-23 00:00:54 +02:00
|
|
|
|
2022-04-12 21:01:18 +02:00
|
|
|
Verifying responses
|
|
|
|
~~~~~~~~~~~~~~~~~~~
|
|
|
|
The class method ``HTTPSignatureAuth.verify()`` can be used to verify responses received back from the server:
|
2017-08-22 21:59:35 +02:00
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
2022-04-13 22:27:43 +02:00
|
|
|
class MyKeyResolver:
|
2022-04-10 23:50:12 +02:00
|
|
|
def resolve_public_key(self, key_id):
|
|
|
|
assert key_id == 'squirrel'
|
|
|
|
return 'monorail_cat'
|
|
|
|
|
2022-04-12 21:01:18 +02:00
|
|
|
response = requests.get(url, auth=auth)
|
|
|
|
HTTPSignatureAuth.verify(response,
|
2022-04-11 17:48:43 +02:00
|
|
|
signature_algorithm=algorithms.HMAC_SHA256,
|
2022-04-13 22:27:43 +02:00
|
|
|
key_resolver=MyKeyResolver())
|
2022-04-10 23:50:12 +02:00
|
|
|
|
2022-04-12 21:01:18 +02:00
|
|
|
More generally, you can reconstruct an arbitrary request using the
|
|
|
|
`Requests API <https://docs.python-requests.org/en/latest/api/#requests.Request>`_ and pass it to ``verify()``:
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
request = requests.Request(...) # Reconstruct the incoming request using the Requests API
|
|
|
|
prepared_request = request.prepare() # Generate a PreparedRequest
|
|
|
|
HTTPSignatureAuth.verify(prepared_request, ...)
|
|
|
|
|
|
|
|
To verify incoming requests and sign responses in the context of an HTTP server, see the
|
|
|
|
`flask-http-signature <https://github.com/pyauth/flask-http-signature>`_ and
|
|
|
|
`http-message-signatures <https://github.com/pyauth/http-message-signatures>`_ packages.
|
|
|
|
|
2022-04-11 02:24:30 +02:00
|
|
|
.. admonition:: See what is signed
|
|
|
|
|
|
|
|
It 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 requests-http-signature, you can ensure that the information signed is what you expect to be signed by only trusting
|
|
|
|
the data returned by the ``verify()`` method::
|
|
|
|
|
|
|
|
verify_result = HTTPSignatureAuth.verify(request, ...)
|
|
|
|
|
2022-04-12 21:53:19 +02:00
|
|
|
See the `API documentation <https://pyauth.github.io/requests-http-signature/#id3>`_ for full details.
|
2017-08-22 21:59:35 +02:00
|
|
|
|
2022-04-10 23:50:12 +02:00
|
|
|
Asymmetric key algorithms
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
To sign or verify messages with an asymmetric key algorithm, set the ``signature_algorithm`` keyword argument to
|
|
|
|
``algorithms.ED25519``, ``algorithms.ECDSA_P256_SHA256``, ``algorithms.RSA_V1_5_SHA256``, or
|
|
|
|
``algorithms.RSA_PSS_SHA512``. Note that signing with rsa-pss-sha512 is not currently supported due to a limitation of
|
|
|
|
the cryptography library.
|
2017-08-22 02:02:39 +02:00
|
|
|
|
2022-04-10 23:50:12 +02:00
|
|
|
For asymmetric key algorithms, you can supply the private key as the ``key`` parameter to the ``HTTPSignatureAuth()``
|
|
|
|
constructor as bytes in the PEM format, or configure the key resolver as follows:
|
2017-08-23 00:00:54 +02:00
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
with open('key.pem', 'rb') as fh:
|
2022-04-11 17:48:43 +02:00
|
|
|
auth = HTTPSignatureAuth(algorithm=algorithms.RSA_V1_5_SHA256,
|
|
|
|
key=fh.read(),
|
|
|
|
key_id=preshared_key_id)
|
2022-04-10 23:50:12 +02:00
|
|
|
requests.get(url, auth=auth)
|
2017-08-22 23:44:25 +02:00
|
|
|
|
2022-04-10 23:50:12 +02:00
|
|
|
class MyKeyResolver:
|
|
|
|
def resolve_public_key(self, key_id: str):
|
|
|
|
return public_key_pem_bytes[key_id]
|
|
|
|
|
|
|
|
def resolve_private_key(self, key_id: str):
|
|
|
|
return private_key_pem_bytes[key_id]
|
|
|
|
|
2022-04-11 17:48:43 +02:00
|
|
|
auth = HTTPSignatureAuth(algorithm=algorithms.RSA_V1_5_SHA256,
|
|
|
|
key=fh.read(),
|
|
|
|
key_resolver=MyKeyResolver())
|
2022-04-10 23:50:12 +02:00
|
|
|
requests.get(url, auth=auth)
|
2017-08-23 00:02:25 +02:00
|
|
|
|
2022-04-11 07:10:03 +02:00
|
|
|
Digest algorithms
|
|
|
|
~~~~~~~~~~~~~~~~~
|
2022-04-15 08:45:53 +02:00
|
|
|
To generate a Content-Digest header using SHA-512 instead of the default SHA-256, subclass ``HTTPSignatureAuth`` as
|
|
|
|
follows::
|
2022-04-11 07:15:13 +02:00
|
|
|
|
2022-04-11 07:10:03 +02:00
|
|
|
class MySigner(HTTPSignatureAuth):
|
2022-04-15 08:45:53 +02:00
|
|
|
default_content_digest_hasher = "sha-512"
|
2022-04-11 07:10:03 +02:00
|
|
|
|
2017-08-22 02:02:39 +02:00
|
|
|
Links
|
|
|
|
-----
|
2022-04-10 23:50:12 +02:00
|
|
|
* `Project home page (GitHub) <https://github.com/pyauth/requests-http-signature>`_
|
2022-04-11 00:13:00 +02:00
|
|
|
* `Package documentation <https://pyauth.github.io/requests-http-signature/>`_
|
2017-08-22 02:02:39 +02:00
|
|
|
* `Package distribution (PyPI) <https://pypi.python.org/pypi/requests-http-signature>`_
|
2022-04-10 23:50:12 +02:00
|
|
|
* `Change log <https://github.com/pyauth/requests-http-signature/blob/master/Changes.rst>`_
|
2022-04-11 07:10:03 +02:00
|
|
|
* `http-message-signatures <https://github.com/pyauth/http-message-signatures>`_ - a dependency of this library that
|
|
|
|
handles much of the implementation
|
|
|
|
* `IETF HTTP Signatures draft <https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-message-signatures>`_
|
2017-08-22 02:02:39 +02:00
|
|
|
|
|
|
|
Bugs
|
|
|
|
~~~~
|
2022-04-10 23:50:12 +02:00
|
|
|
Please report bugs, issues, feature requests, etc. on `GitHub <https://github.com/pyauth/requests-http-signature/issues>`_.
|
2017-08-22 02:02:39 +02:00
|
|
|
|
|
|
|
License
|
|
|
|
-------
|
|
|
|
Licensed under the terms of the `Apache License, Version 2.0 <http://www.apache.org/licenses/LICENSE-2.0>`_.
|