All Projects → dajiaji → pyseto

dajiaji / pyseto

Licence: MIT license
A Python implementation of PASETO and PASERK.

Programming Languages

python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to pyseto

NFT.net
An engine developed with .NET Core to generate NFT's through a graphical interface. Simple as that, in the best Grab & Go style.
Stars: ✭ 294 (+1300%)
Mutual labels:  token
smooth-signature
H5带笔锋手写签名,支持PC端和移动端,任何前端框架均可使用
Stars: ✭ 474 (+2157.14%)
Mutual labels:  signature
crowntool
Multi Tool with many functions coming
Stars: ✭ 55 (+161.9%)
Mutual labels:  token
gtoken
基于gf框架的token插件,通过服务端验证方式实现token认证;
Stars: ✭ 181 (+761.9%)
Mutual labels:  token
qdigidoc
DEPRECATED DigiDoc3 Client is a program that can be used to sign digitally with ID-card and Mobile-ID, check the validity of digital signatures and open and save documents inside the signature container.
Stars: ✭ 25 (+19.05%)
Mutual labels:  signature
prune-horst
Signature scheme submitted to NIST's Post-Quantum Cryptography Project
Stars: ✭ 23 (+9.52%)
Mutual labels:  signature
crypto-watchdog
Crypto Watchdog is an open-source developer friendly project, periodically queries crypto market and notifies potential pumps & recently added tokens/coins via web-hooks.
Stars: ✭ 22 (+4.76%)
Mutual labels:  token
gravity-sphincs
Signature scheme submitted to NIST's Post-Quantum Cryptography Project
Stars: ✭ 67 (+219.05%)
Mutual labels:  signature
laravel-web3
Laravel SDK wrapper for the Web3 PHP API client that interacts with the Ethereum blockchain.
Stars: ✭ 85 (+304.76%)
Mutual labels:  token
ios-application
A native, lightweight and secure one-time-password (OTP) client built for iOS; Raivo OTP!
Stars: ✭ 581 (+2666.67%)
Mutual labels:  token
AutomatedOutlookSignature
PowerShell script to automate the creation of Outlook signatures using Active Directory attributes.
Stars: ✭ 36 (+71.43%)
Mutual labels:  signature
mod authnz jwt
An authentication module for Apache httpd using JSON Web Tokens
Stars: ✭ 74 (+252.38%)
Mutual labels:  token
macaroons-rs
Macaroons: bearer credentials with caveats for distributed authorization
Stars: ✭ 62 (+195.24%)
Mutual labels:  token
Microstaking
No description or website provided.
Stars: ✭ 26 (+23.81%)
Mutual labels:  token
phalcon-micro-rest-api-skeleton
This is a basic API REST skeleton written on Phalcon PHP. Great For building an MVP for your frontend app (Vue, react, angular, or anything that can consume an API)
Stars: ✭ 57 (+171.43%)
Mutual labels:  token
BatchPayments
A gas conscious batch payment implementation
Stars: ✭ 27 (+28.57%)
Mutual labels:  token
react-native-signview
Signature view for react native(Android + IOS)
Stars: ✭ 15 (-28.57%)
Mutual labels:  signature
Discord-AIO
Discord AIO (All In One) - discord stealer/token grabber builder with token checks, webhook spammer, obfuscation, encryption, crypto miner, RAT and a lot of extra features.
Stars: ✭ 105 (+400%)
Mutual labels:  token
blockstarter
This is a white label solution to create a contribution crypto-wallet that can be used in your ICO campaign.
Stars: ✭ 21 (+0%)
Mutual labels:  token
Get-Discord-Token
Automatically get discord token from browser.
Stars: ✭ 46 (+119.05%)
Mutual labels:  token

PySETO - A Python implementation of PASETO/PASERK

PyPI version PyPI - Python Version Documentation Status Github CI codecov

PySETO is a PASETO (Platform-Agnostic SEcurity TOkens)/PASERK (Platform-Agnostic Serialized Keys) implementation written in Python which supports all of the versions (v1, v2, v3 and v4) and purposes (public and local) and has passed all of the official tests.

You can install PySETO with pip:

$ pip install pyseto

PySETO can be used in ease as follows (in case of v4.public):

import pyseto
from pyseto import Key

private_key_pem = b"-----BEGIN PRIVATE KEY-----\nMC4CAQAwBQYDK2VwBCIEILTL+0PfTOIQcn2VPkpxMwf6Gbt9n4UEFDjZ4RuUKjd0\n-----END PRIVATE KEY-----"
public_key_pem = b"-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAHrnbu7wEfAP9cGBOAHHwmH4Wsot1ciXBHwBBXQ4gsaI=\n-----END PUBLIC KEY-----"


# Create a PASETO token.
private_key = Key.new(version=4, purpose="public", key=private_key_pem)
token = pyseto.encode(private_key, b'{"data": "this is a signed message", "exp": "2022-01-01T00:00:00+00:00"}')

# Decode and verify a PASETO token.
public_key = Key.new(version=4, purpose="public", key=public_key_pem)
decoded = pyseto.decode(public_key, token)

assert token == b'v4.public.eyJkYXRhIjogInRoaXMgaXMgYSBzaWduZWQgbWVzc2FnZSIsICJleHAiOiAiMjAyMi0wMS0wMVQwMDowMDowMCswMDowMCJ9l1YiKei2FESvHBSGPkn70eFO1hv3tXH0jph1IfZyEfgm3t1DjkYqD5r4aHWZm1eZs_3_bZ9pBQlZGp0DPSdzDg'
assert decoded.payload == b'{"data": "this is a signed message", "exp": "2022-01-01T00:00:00+00:00"}'

See following contents or Documentation for details.

Index

Installation

You can install PySETO with pip:

$ pip install pyseto

Supported PASETO Versions

PySETO supports all of PASETO versions and purposes below:

v4 v3 v2 v1
local
public

Supported PASERK Types

PySETO also supports PASERK (Platform-Agnostic Serialized Keys). Currently, following PASERK types are supported:

v4 v3 v2 v1
lid
sid
pid
local
secret
public
seal
local-wrap
secret-wrap
local-pw
secret-pw

PASETO Usage

By using this PySETO, you can easily create, decode and verify PASETO tokens. Here are sample codes that handle version 4 PySETO tokens.

Please refer to the Documentation for all usage examples including other versions.

Basic usage: v4.public

v4.public is one of current PASETO versions to be used for asymmetric authentication (public key signatures).

import pyseto
from pyseto import Key

private_key_pem = b"-----BEGIN PRIVATE KEY-----\nMC4CAQAwBQYDK2VwBCIEILTL+0PfTOIQcn2VPkpxMwf6Gbt9n4UEFDjZ4RuUKjd0\n-----END PRIVATE KEY-----"
public_key_pem = b"-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAHrnbu7wEfAP9cGBOAHHwmH4Wsot1ciXBHwBBXQ4gsaI=\n-----END PUBLIC KEY-----"

private_key = Key.new(version=4, purpose="public", key=private_key_pem)
token = pyseto.encode(private_key, b'{"data": "this is a signed message", "exp": "2022-01-01T00:00:00+00:00"}')

public_key = Key.new(version=4, purpose="public", key=public_key_pem)
decoded = pyseto.decode(public_key, token)

assert token == b'v4.public.eyJkYXRhIjogInRoaXMgaXMgYSBzaWduZWQgbWVzc2FnZSIsICJleHAiOiAiMjAyMi0wMS0wMVQwMDowMDowMCswMDowMCJ9l1YiKei2FESvHBSGPkn70eFO1hv3tXH0jph1IfZyEfgm3t1DjkYqD5r4aHWZm1eZs_3_bZ9pBQlZGp0DPSdzDg'
assert decoded.payload == b'{"data": "this is a signed message", "exp": "2022-01-01T00:00:00+00:00"}'

Basic usage: v4.local

v4.local is one of current PASETO versions to be used for symmetric authenticated encryption.

import pyseto
from pyseto import Key

key = Key.new(version=4, purpose="local", key=b"our-secret")
token = pyseto.encode(key, b'{"data": "this is a signed message", "exp": "2022-01-01T00:00:00+00:00"}')

decoded = pyseto.decode(key, token)

assert decoded.payload == b'{"data": "this is a signed message", "exp": "2022-01-01T00:00:00+00:00"}'

Using serializer/deserializer for payload and footer

By using serializer and deserializer, you can encode/decode a dict-typed payload and footer included in PASETO tokens into an arbitrary format. The following example shows that the payload and the footer in a PASETO token are encoded/decoded as JSON formatted data. When specifing dict-typed payload, exp parameter can be used to set the expiration time (seconds) of the token.

import json
import pyseto
from pyseto import Key

private_key_pem = b"-----BEGIN PRIVATE KEY-----\nMC4CAQAwBQYDK2VwBCIEILTL+0PfTOIQcn2VPkpxMwf6Gbt9n4UEFDjZ4RuUKjd0\n-----END PRIVATE KEY-----"
public_key_pem = b"-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAHrnbu7wEfAP9cGBOAHHwmH4Wsot1ciXBHwBBXQ4gsaI=\n-----END PUBLIC KEY-----"

private_key = Key.new(version=4, purpose="public", key=private_key_pem)
public_key = Key.new(version=4, purpose="public", key=public_key_pem)
token = pyseto.encode(
    private_key,
    {"data": "this is a signed message"},
    footer={"kid": public_key.to_paserk_id()},
    serializer=json,
    exp=3600,
)

decoded = pyseto.decode(public_key, token, deserializer=json)

assert decoded.payload["data"] == "this is a signed message"
assert decoded.payload["exp"] == "2021-11-11T00:00:00+00:00"
assert decoded.footer["kid"] == "k4.pid.yh4-bJYjOYAG6CWy0zsfPmpKylxS7uAWrxqVmBN2KAiJ"

Using Paseto class for handling registered claims

By using Paseto class, you can change the default value of exp (the expiration date ot tokens), whether to include an iat claim, and other settings.

Note that pyseto.encode() and pyseto.decode() are aliases to the encode() and decode() of the global "Paseto" class instance created with the default settings.

import json
import pyseto
from pyseto import Key, Paseto

private_key_pem = b"-----BEGIN PRIVATE KEY-----\nMC4CAQAwBQYDK2VwBCIEILTL+0PfTOIQcn2VPkpxMwf6Gbt9n4UEFDjZ4RuUKjd0\n-----END PRIVATE KEY-----"
public_key_pem = b"-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAHrnbu7wEfAP9cGBOAHHwmH4Wsot1ciXBHwBBXQ4gsaI=\n-----END PUBLIC KEY-----"

private_key = Key.new(version=4, purpose="public", key=private_key_pem)
paseto = Paseto.new(exp=3600, include_iat=True) # Default values are exp=0(not specified) and including_iat=False
token = paseto.encode(
    private_key,
    {"data": "this is a signed message"},
    serializer=json,
)

public_key = Key.new(version=4, purpose="public", key=public_key_pem)
decoded = pyseto.decode(public_key, token, deserializer=json)

assert decoded.payload["data"] == "this is a signed message"
assert decoded.payload["iat"] == "2021-11-11T00:00:00+00:00"
assert decoded.payload["exp"] == "2021-11-11T01:00:00+00:00"

PASERK Usage

PASERK (Platform-Agnostic Serialized Keys) is an extension to PASETO that provides key-wrapping and serialization.

Serializing/Deserializing PASERK

As shown in the examples above, the pyseto.Key used for encryption and signature can be generated from PASERK or converted to PASERK as follows:

import pyseto
from pyseto import Key

# pyseto.Key can be generated from PASERK.
symmetric_key = Key.new(version=4, purpose="local", key=b"our-secret")
private_key = Key.from_paserk("k4.secret.tMv7Q99M4hByfZU-SnEzB_oZu32fhQQUONnhG5QqN3Qeudu7vAR8A_1wYE4AcfCYfhayi3VyJcEfAEFdDiCxog")
public_key = Key.from_paserk("k4.public.Hrnbu7wEfAP9cGBOAHHwmH4Wsot1ciXBHwBBXQ4gsaI")

token = pyseto.encode(private_key, b'{"data": "this is a signed message", "exp": "2022-01-01T00:00:00+00:00"}')
decoded = pyseto.decode(public_key, token)

assert decoded.payload == b'{"data": "this is a signed message", "exp": "2022-01-01T00:00:00+00:00"}'

# PASERK can be derived from pyseto.Key.
assert symmetric_key.to_paserk() == "k4.local.b3VyLXNlY3JldA"
assert private_key.to_paserk() == "k4.secret.tMv7Q99M4hByfZU-SnEzB_oZu32fhQQUONnhG5QqN3Qeudu7vAR8A_1wYE4AcfCYfhayi3VyJcEfAEFdDiCxog"
assert public_key.to_paserk() == "k4.public.Hrnbu7wEfAP9cGBOAHHwmH4Wsot1ciXBHwBBXQ4gsaI"

Serializing PASERK ID

pyseto.Key can also be converted to PASERK ID as follows:

import pyseto
from pyseto import Key

# pyseto.Key can be generated from PASERK.
symmetric_key = Key.new(version=4, purpose="local", key=b"our-secret")
private_key = Key.from_paserk("k4.secret.tMv7Q99M4hByfZU-SnEzB_oZu32fhQQUONnhG5QqN3Qeudu7vAR8A_1wYE4AcfCYfhayi3VyJcEfAEFdDiCxog")
public_key = Key.from_paserk("k4.public.Hrnbu7wEfAP9cGBOAHHwmH4Wsot1ciXBHwBBXQ4gsaI")

# PASERK ID can be derived from pyseto.Key.
assert symmetric_key.to_paserk_id() == "k4.lid._D6kgTzxgiPGk35gMj9bukgj4En2H94u22wVX9zaoh05"
assert private_key.to_paserk() == "k4.secret.tMv7Q99M4hByfZU-SnEzB_oZu32fhQQUONnhG5QqN3Qeudu7vAR8A_1wYE4AcfCYfhayi3VyJcEfAEFdDiCxog"
assert public_key.to_paserk_id() == "k4.pid.yh4-bJYjOYAG6CWy0zsfPmpKylxS7uAWrxqVmBN2KAiJ"

Key Wrapping

If you call to_paserk with wrapping_key, you can get a wrapped (encrypted) PASERK with the wrapping key. The wrapped PASERK can be decrypted by calling from_paserk with wrapping key.

In case of local-wrap.pie:

import pyseto
from pyseto import Key

raw_key = Key.new(version=4, purpose="local", key=b"our-secret")
wrapping_key = token_bytes(32)
wpk = raw_key.to_paserk(wrapping_key=wrapping_key)
token = pyseto.encode(raw_key, b'{"data": "this is a signed message", "exp": "2022-01-01T00:00:00+00:00"}')

unwrapped_key = Key.from_paserk(wpk, wrapping_key=wrapping_key)
decoded = pyseto.decode(unwrapped_key, token)

# assert wpk == "k4.local-wrap.pie.TNKEwC4K1xBcgJ_GiwWAoRlQFE33HJO3oN9DHEZ05pieSCd-W7bgAL64VG9TZ_pBkuNBFHNrfOGHtnfnhYGdbz5-x3CxShhPJxg"
assert decoded.payload == b'{"data": "this is a signed message", "exp": "2022-01-01T00:00:00+00:00"}'

In case of secret-wrap.pie:

import pyseto
from pyseto import Key

raw_private_key = Key.from_paserk(
    "k4.secret.tMv7Q99M4hByfZU-SnEzB_oZu32fhQQUONnhG5QqN3Qeudu7vAR8A_1wYE4AcfCYfhayi3VyJcEfAEFdDiCxog"
)
wrapping_key = token_bytes(32)
wpk = raw_private_key.to_paserk(wrapping_key=wrapping_key)
unwrapped_private_key = Key.from_paserk(wpk, wrapping_key=wrapping_key)
token = pyseto.encode(unwrapped_private_key, b'{"data": "this is a signed message", "exp": "2022-01-01T00:00:00+00:00"}')

public_key = Key.from_paserk("k4.public.Hrnbu7wEfAP9cGBOAHHwmH4Wsot1ciXBHwBBXQ4gsaI")
decoded = pyseto.decode(public_key, token)

# assert wpk == "k4.secret-wrap.pie.excv7V4-NaECy5hpji-tkSkMvyjsAgNxA-mGALgdjyvGNyDlTb89bJ35R1e3tILgbMpEW5WXMXzySe2T-sBz-ZAcs1j7rbD3ZWvsBTM6K5N9wWfAxbR4ppCXH_H5__9yY-kBaF2NimyAJyduhOhSmqLm6TTSucpAOakEJOXePW8"
assert decoded.payload == b'{"data": "this is a signed message", "exp": "2022-01-01T00:00:00+00:00"}'

Password-based Key Encryption

If you call to_paserk with password, you can get a wrapped (encrypted) PASERK with the password. The wrapped PASERK can be decrypted by calling from_paserk with passwrod.

In case of local-pw:

import pyseto
from pyseto import Key

raw_key = Key.new(version=4, purpose="local", key=b"our-secret")
token = pyseto.encode(raw_key, b'{"data": "this is a signed message", "exp": "2022-01-01T00:00:00+00:00"}')

wpk = raw_key.to_paserk(password="our-secret")
unwrapped_key = Key.from_paserk(wpk, password="our-secret")
decoded = pyseto.decode(unwrapped_key, token)

# assert wpk == "k4.local-pw.HrCs9Pu-2LB0l7jkHB-x2gAAAAAA8AAAAAAAAgAAAAGttW0IHZjQCHJdg-Vc3tqO_GSLR4vzLl-yrKk2I-l8YHj6jWpC0lQB2Z7uzTtVyV1rd_EZQPzHdw5VOtyucP0FkCU"
assert decoded.payload == b'{"data": "this is a signed message", "exp": "2022-01-01T00:00:00+00:00"}'

In case of secret-pw:

import pyseto
from pyseto import Key

raw_private_key = Key.from_paserk(
    "k4.secret.tMv7Q99M4hByfZU-SnEzB_oZu32fhQQUONnhG5QqN3Qeudu7vAR8A_1wYE4AcfCYfhayi3VyJcEfAEFdDiCxog"
)
wpk = raw_private_key.to_paserk(password="our-secret")
unwrapped_private_key = Key.from_paserk(wpk, password="our-secret")
token = pyseto.encode(unwrapped_private_key, b'{"data": "this is a signed message", "exp": "2022-01-01T00:00:00+00:00"}')

public_key = Key.from_paserk(
    "k4.public.Hrnbu7wEfAP9cGBOAHHwmH4Wsot1ciXBHwBBXQ4gsaI"
)
decoded = pyseto.decode(public_key, token)

# assert wpk == "k4.secret-pw.MEMW4K1MaD5nWigCLyEyFAAAAAAA8AAAAAAAAgAAAAFU-tArtryNVjS2n2hCYiM11V6tOyuIog69Bjb0yNZanrLJ3afGclb3kPzQ6IhK8ob9E4QgRdEALGWCizZ0RCPFF_M95IQDfmdYKC0Er656UgKUK4UKG9JlxP4o81UwoJoZYz_D1zTlltipEa5RiNvUtNU8vLKoGSY"
assert decoded.payload == b'{"data": "this is a signed message", "exp": "2022-01-01T00:00:00+00:00"}'

Asymmetric Encryption

At this time, PySETO supports asymmetric encryption (key sealing) for v2 and v4.

import pyseto
from pyseto import Key

private_key_pem = b"-----BEGIN PRIVATE KEY-----\nMC4CAQAwBQYDK2VuBCIEIFAF7jSCZHFgWvC8hUkXr55Az6Pot2g4zOAUxck0/6x8\n-----END PRIVATE KEY-----"
public_key_pem = b"-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VuAyEAFv8IXsICYj0paznDK/99GyCsFOIGnfY87ayyNSIvSB4=\n-----END PUBLIC KEY-----"

raw_key = Key.new(version=4, purpose="local", key=b"our-secret")
token = pyseto.encode(
    raw_key,
    b'{"data": "this is a signed message", "exp": "2022-01-01T00:00:00+00:00"}',
)

sealed_key = raw_key.to_paserk(sealing_key=public_key_pem)
unsealed_key = Key.from_paserk(sealed_key, unsealing_key=private_key_pem)
decoded = pyseto.decode(unsealed_key, token)

assert (
    decoded.payload
    == b'{"data": "this is a signed message", "exp": "2022-01-01T00:00:00+00:00"}'
)

Key searing for v1 and v3 have not been supported yet.

API Reference

See Documentation.

Tests

You can run tests from the project root after cloning with:

$ tox

Contributing

We welcome all kind of contributions, filing issues, suggesting new features or sending PRs.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].