A library to use BLAKE in keyed hashing mode to sign and verify signed data
Project description
Blake2Signer
The goal of this project is to provide a simple and straightforward way to securely sign data using BLAKE in keyed hashing mode, using a secret key. This can be used, in example, when you need to send some data that could be tampered by the user, like a payment authorization, or a login token. This data travels in plaintext, and can be read, but it can't be modified in any way once signed!.
Why would I need to use it?
- To sign data that needs to be sent through an untrusted channel, like signing a cookie with user data and providing it to the user, so the user can identify themselves with the rest of the system safely.
- To save database lookups by checking signed data, like an account activation or password reset link where you can sign the user id and then verify it securely without using a database.
- To prevent data tampering, like signing some value that goes in a form hidden field such as the user type (admin or regular) so that the user can't trick the value.
- To easily express intent when signing data, like sharing a single secret key between signers to simplify app configuration and use the
personalisation
parameter to prevent signed data misuse.
In short, never trust user input, always verify. This module helps you do that.
Why would I want to use it?
Because it is a relatively small (around 900 logical lines of code, core around 400), simple (the public API has only a couple of methods) yet very customizable and fast data signer. My idea is to keep it as uncomplicated as possible without much room to become a footgun. All defaults are very correct (secure), and everything just works out of the box.
There are much better packages for other or more general use cases, so if you feel this doesn't satisfy your needs, please leave a feature request or consider using itsdangerous, Django's signer, pypaseto, pyjwt or others like those.
Goals
- Be safe and secure.
- Be simple and straightforward.
- Follow semver.
- Be always typed.
- No dependencies (besides dev).
- 100% coverage.
Secondary goals
- If possible, maintain current active Python versions (3.8+).
- If possible, support Python implementations other than CPython.
Installing
This package is hosted on PyPi so just:
python3 -m pip install blake2signer
poetry add blake2signer
pipenv install blake2signer
You can check the releases' page for package hashes and signatures.
Note: if you want to use BLAKE3, you need to install the blake3
package, until it arrives to core (which may or may not happen). Alternatively, you can install this package with extras:
python3 -m pip install blake2signer[blake3]
poetry add blake2signer[blake3]
pipenv install blake2signer[blake3]
Requirements
Only Python is required; this module doesn't have dependencies besides those used for development, and the optional blake3
.
Versions currently tested (check the pipelines):
- CPython 3.8
- CPython 3.9
- CPython 3.10
- CPython 3.11
- CPython 3.12
- CPython 3.13-pre
- PyPy 3.8
- If you are contributing to this project under PyPy, read the contrib notes first.
- PyPy 3.9
- If you are contributing to this project under PyPy, read the contrib notes first.
- PyPy 3.10
- If you are contributing to this project under PyPy, read the contrib notes first.
- Stackless 3.8
- If you are contributing to this project under Stackless, read the contrib notes first.
Tl; Dr Example
"""Tl;dr example."""
from datetime import timedelta
from blake2signer import Blake2SerializerSigner
from blake2signer import errors
secret = b'secure-secret-that-nobody-knows!'
# Some arbitrary data to sign
data = {'user_id': 1, 'is_admin': True, 'username': 'hackan'}
signer = Blake2SerializerSigner(
secret,
max_age=timedelta(days=1), # Add a timestamp to the signature
personalisation=b'the-cookie-signer',
)
# Sign and i.e. store the data in a cookie
signed = signer.dumps(data) # Compression is enabled by default
# If compressing data turns out to be detrimental then data won't be
# compressed. If you know that from beforehand and don't need compression, you
# can disable it:
# signed = signer.dumps(data, compress=False)
# Additionally, you can force compression nevertheless:
# signed = signer.dumps(data, force_compression=True)
cookie = {'data': signed}
# To verify and recover data simply use `loads`: you will either get the data or
# a `SignerError` subclass exception.
try:
unsigned = signer.loads(cookie.get('data', ''))
except errors.SignedDataError: # See more about errors in the docs
# Can't trust on given data
unsigned = {}
print(unsigned) # {'user_id': 1, 'is_admin': True, 'username': 'hackan'}
Find more details and examples in the docs.
Tip: all modules, classes, methods and functions are documented so don't doubt asking for
help()
.
Signers
This module provides three signer classes:
- Blake2SerializerSigner: a signer class that handles data serialization, compression and encoding along with salted signing and salted timestamped signing. Its public methods are
dumps
,loads
,dumps_parts
andloads_parts
, anddump
andload
for files. - Blake2Signer: a signer class that signs plain
bytes
orstr
data. Its public methods aresign
,unsign
,sign_parts
andunsign_parts
. - Blake2TimestampSigner: a signer class that timestamp signs plain
bytes
orstr
data. Its public methods aresign
,unsign
,sign_parts
andunsign_parts
.
You should generally go for Blake2SerializerSigner, given that it's the most versatile of the three, unless you need to deal with plain bytes
or strings. Check details about signers and usage examples to learn more.
Documentation
Check out this project docs online, or locally with inv docs
. Alternatively, build them locally using inv docs --build
.
Getting help
For help, support, and discussions, come to our Matrix room. For issues, please use the Gitlab issue tracker.
Notice
I'm not a cryptoexpert, so this project needs a security review. If you are one and can do it, please contact me.
Contributors
In alphabetical ordering, with short description about contribution:
- Erus: docs title logo, code review.
- NoonSleeper: project icons.
License
Blake2Signer is made by HacKan under MPL v2.0. You are free to use, share, modify and share modifications under the terms of that license. Derived works may link back to the canonical repository: https://gitlab.com/hackancuba/blake2signer
.
Copyright (C) 2020-2024 HacKan (https://hackan.net)
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
Blake2Signer icons by NoonSleeper are licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. You are free to use, share, modify and share modifications under the terms of that license. They were based on Blake2Signer logo by HacKan which was based on this sword by Hamza Wahbi and this signature by Nick Bluth, both licensed under CC BY 3.0, and inspired by It's dangerous logo.
Check them out in the icons subdir.
Blake2Signer with Logo by Erus is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. You are free to use, share, modify and share modifications under the terms of that license. It uses OFL licensed Bilbo font.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for blake2signer-3.1.0-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 4897c72668bedb638944cda9323594e240284ddbdf16e27687b097b714367784 |
|
MD5 | 6b957057aa3ccee5d08c34c0a5d199d9 |
|
BLAKE2b-256 | bfd08e28ff64d91a02fa85cdc6cd54f094228504f9fdd2fefcd6fb0878226e79 |