Ska
Sign data using symmetric-key algorithm encryption. Validate signed data and identify possible validation errors. Uses sha-(1, 224, 256, 385 and 512)/hmac for signature encryption. Custom hash algorithms are allowed. Useful shortcut functions for signing (and validating) dictionaries and URLs.
Install / Use
/learn @barseghyanartur/SkaREADME
=== ska
Lets you easily sign data, using symmetric-key algorithm encryption. Allows you to validate signed data and identify possible validation errors. Uses sha-(1, 224, 256, 385 and 512)/hmac for signature encryption. Allows to use custom hash algorithms. Comes with shortcut functions for signing (and validating) dictionaries and URLs.
.. image:: https://img.shields.io/pypi/v/ska.svg :target: https://pypi.python.org/pypi/ska :alt: PyPI Version
.. image:: https://img.shields.io/pypi/pyversions/ska.svg :target: https://pypi.python.org/pypi/ska/ :alt: Supported Python versions
.. image:: https://github.com/barseghyanartur/ska/workflows/test/badge.svg :target: https://github.com/barseghyanartur/ska/actions :alt: Build Status
.. image:: https://readthedocs.org/projects/ska/badge/?version=latest :target: http://ska.readthedocs.io/en/latest/?badge=latest :alt: Documentation Status
.. image:: https://img.shields.io/badge/docs-llms.txt-blue :target: https://ska.readthedocs.io/en/latest/llms.txt :alt: llms.txt - documentation for LLMs
.. image:: https://img.shields.io/badge/license-GPL--2.0--only%20OR%20LGPL--2.1--or--later-blue.svg :target: https://github.com/barseghyanartur/ska/#License :alt: GPL-2.0-only OR LGPL-2.1-or-later
.. image:: https://coveralls.io/repos/github/barseghyanartur/ska/badge.svg?branch=main&service=github :target: https://coveralls.io/github/barseghyanartur/ska?branch=main :alt: Coverage
Key concepts
Hosts, that communicate with each other, share the Secret Key, which is used to sign data (requests). Secret key is never sent around.
One of the cases is signing of HTTP requests. Each (HTTP) request is signed
on the sender side using the shared Secret Key and as an outcome produces the
triple (signature, auth_user, valid_until) which are used to sign
the requests.
signature(str): Signature generated.auth_user(str): User making the request. Can be anything.valid_until(floatorstr): Signature expiration time (Unix timestamp).
On the recipient side, (HTTP request) data is validated using the shared Secret Key. It's being checked whether signature is valid and not expired.
.. code-block:: text
┌─────────────┐ Data ┌─────────────┐
│ Host 1 ├────────────────────────────>│ Host 2 │
│ ─────────── │ │ ─────────── │
│ secret key │ │ secret key │
│ 'my-secret' │<────────────────────────────┤ 'my-secret' │
└─────────────┘ Data └─────────────┘
Features
Core ska module
- Sign dictionaries.
- Validate signed dictionaries.
- Sign URLs. Append and sign additional URL data.
- Validate URLs.
- Use one of the built-in algorythms (HMAC SHA-1, HMAC SHA-224, HMAC SHA-256, HMAC SHA-384 or HMAC SHA-512) or define a custom one.
Django ska module (ska.contrib.django.ska)
- Model decorators for signing absolute URLs. View (including class-based views) decorators for protecting views to authorised parties only (no authentication required).
- Authentication backend for Django based on the signatures (tokens) generated
using
ska, which allows you to get a password-less login to Django web site. Multiple Secret Keys (per provider) supported. Comes with handy callbacks (possible to customise per provider) for various states of authentication. - Template tags for signing URLs from within templates.
django-constanceintegration (for password-less authentication).Django REST Framework integration_ (for protecting ViewSets, obtaining JWT tokens for authentication).
Prerequisites
Present
- Core
skamodule requires Python 3.10+. - Django
skamodule (ska.contrib.django.ska) requires the mentioned above plus Django 4.2+. Additionally, certain versions ofdjango-constanceanddjangorestframeworkare required. Specific version requirement primarily depends on the used Django version. Check theexample requirements <https://github.com/barseghyanartur/ska/tree/main/examples/requirements>_ to find out which versions ofdjango-constanceanddjangorestframeworkhave been tested with specific Django versions.
Past
.. note::
In future releases (any time) compatibility with no-longer-supported
versions might/will be wiped out.
- Dropping support of Python 3.9 has been announced in version 1.11.2. As of 1.11 everything still worked.
- Dropping support of Python 3.8 has been announced in version 1.11. As of 1.10 everything still worked.
- Dropping support of Python 3.6 and 3.7 has been announced in version 1.10. As of 1.9.1 everything still worked.
- Dropping support of Python 2.7 and 3.5 has been announced in version 1.8. As of 1.7.5 everything still worked.
- Dropping support of Python 3.4 has been announced in version 1.6.8. As of 1.6.8 everything still worked.
- Dropping support of Django 3.1, 3.2 and 4.1 has been announced in version 1.11. As of 1.10 everything is still backwards compatible with mentioned versions.
- Dropping support of Django 2.2, 3.0, 3.1 and 4.0 has been announced in version 1.10. As of 1.9.1 everything is still backwards compatible with mentioned versions.
- Dropping support of Django 1.5, 1.6 and 1.7 has been announced in version 1.6. As of 1.6 everything is still backwards compatible with mentioned versions.
- Dropping support of Python 2.6 and 3.3 has been announced in version 1.6. As of 1.6 everything is still backwards compatible (as much as it's possible within this package) with mentioned versions.
Eco-system
Need ska for other languages? Check the following affiliated projects:
skajs <https://github.com/barseghyanartur/skajs>_:skaimplementation for NodeJS (both CommonJS and ESM are supported, Node >= 14).skaphp <https://github.com/barseghyanartur/skaphp>_:skaimplementation for PHP (>= 7.2).
Generated signatures are inter-compatible between Python, NodeJS and PHP implementations.
Installation
Latest stable version from PyPI:
.. code-block:: sh
pip install ska
or latest development version from GitHub.
.. code-block:: sh
pip install https://github.com/barseghyanartur/ska/archive/main.tar.gz
Usage examples
For integration with Django, see the Django integration_ section.
Basic usage
Pure Python usage.
Sender side
Signing URLs is as simple as follows.
Required imports.
.. code-block:: python
:name: test_signing_urls
from ska import sign_url
Producing a signed URL.
.. continue: test_signing_urls
.. code-block:: python
:name: test_signing_urls_sign_url_function
signed_url = sign_url(
auth_user='user',
secret_key='your-secret_key',
url='http://e.com/api/'
)
.. code-block:: text
GET http://e.com/api/?valid_until=1378045287.0&auth_user=user&signature=YlZpLFsjUKBalL4x5trhkeEgqE8%3D
Default lifetime of a signature is 10 minutes (600 seconds). If you want it
to be different, provide a ``lifetime`` argument to ``sign_url`` function.
Default name of the (GET) param holding the generated signature value
is ``signature``. If you want it to be different, provide a ``signature_param``
argument to ``sign_url`` function.
Default name of the (GET) param holding the ``auth_user`` value is
``auth_user``. If you want it to be different, provide a ``auth_user_param``
argument to ``sign_url`` function.
Default name of the (GET) param holding the ``valid_until`` value is
`valid_until`. If you want it to be different, provide a ``valid_until_param``
argument to ``sign_url`` function.
Note, that by default a suffix '?' is added after the given ``url`` and
generated signature params. If you want that suffix to be custom, provide a
``suffix`` argument to the ``sign_url`` function. If you want it to be gone,
set its' value to empty string.
With all customisations, it would look as follows:
.. continue: test_signing_urls
.. code-block:: python
:name: test_signing_urls_customisations
from ska import HMACSHA512Signature # Use HMAC SHA-512 algorithm
signed_url = sign_url(
auth_user='user',
secret_key='your-secret_key',
lifetime=120,
url='http://e.com/api/',
signature_param='signature',
auth_user_param='auth_user',
valid_until_param='valid_until',
signature_cls=HMACSHA512Signature
)
It's also possible to add additional data to the signature by providing a
``extra`` argument (dict). Note, that additional data is signed as well.
If request is somehow tampered (values vary from originally provided ones),
signature becomes invalid.
.. continue: test_signing_urls
.. code-block:: python
:name: test_signing_urls_additional_data
sign_url(
auth_user='user',
secret_key='your-secret_key',
url='http://e.com/api/',
extra={
'email': 'doe@example.com',
'last_name': 'Doe',
'first_name': 'Joe'
}
)
You may now proceed with the signed URL request. If you use the famous
``requests`` library, it would be as follows.
.. code-block:: python
import requests
requests.get(signed_url)
If you want to use POST method instead, you would likely want to get a
dictionary back, in order to append it to the POST data later.
Required imports.
.. code-block:: python
:name: test_signing_dicts
from ska import signature_to_dict
Producing a dictionary containing the signature data, ready to be put into
the request (for example POST) data. All customisations mentioned above for
the ``sign_url`` function, also apply to the ``signature_to_dict``:
.. continue: test_signing_dicts
.. code-block:: python
:name: test_signing_dicts_signature_to_dict
si
