Paseto
This repository houses an elixir implementation of Paseto
From the reference implementation of Paseto:
What is Paseto?
Paseto (Platform-Agnostic SEcurity TOkens) is a specification and reference implementation for secure stateless tokens.
Key Differences between Paseto and JWT
Unlike JSON Web Tokens (JWT), which gives developers more than enough rope with which to hang themselves, Paseto only allows secure operations. JWT gives you "algorithm agility", Paseto gives you "versioned protocols". It's incredibly unlikely that you'll be able to use Paseto in an insecure way.
Caution: Neither JWT nor Paseto were designed for stateless session management. Paseto is suitable for tamper-proof cookies, but cannot prevent replay attacks by itself.
Paseto
Paseto Example 1
v2.local.QAxIpVe-ECVNI1z4xQbm_qQYomyT3h8FtV8bxkz8pBJWkT8f7HtlOpbroPDEZUKop_vaglyp76CzYy375cHmKCW8e1CCkV0Lflu4GTDyXMqQdpZMM1E6OaoQW27gaRSvWBrR3IgbFIa0AkuUFw.UGFyYWdvbiBJbml0aWF0aXZlIEVudGVycHJpc2Vz
This decodes to:
- Version:
v2 - Purpose:
local(shared-key authenticated encryption) - Payload (hex-encoded):
400c48a557be10254d235cf8c506e6fea418a26c93de1f05b55f1bc64cfca41256913f1fec7b653a96eba0f0c46542a8a7fbda825ca9efa0b3632dfbe5c1e62825bc7b5082915d0b7e5bb81930f25cca9076964c33513a39aa105b6ee06914af581ad1dc881b1486b4024b9417
- Nonce:
400c48a557be10254d235cf8c506e6fea418a26c93de1f05 - Authentication tag:
6914af581ad1dc881b1486b4024b9417
- Nonce:
- Decrypted Payload:
{"data": "this is a signed message","exp": "2039-01-01T00:00:00+00:00"}
- Key used in this example (hex-encoded):
707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f
- Key used in this example (hex-encoded):
- Footer:
Paragon Initiative Enterprises
Paseto Example 2
v2.public.eyJleHAiOiIyMDM5LTAxLTAxVDAwOjAwOjAwKzAwOjAwIiwiZGF0YSI6InRoaXMgaXMgYSBzaWduZWQgbWVzc2FnZSJ91gC7-jCWsN3mv4uJaZxZp0btLJgcyVwL-svJD7f4IHyGteKe3HTLjHYTGHI1MtCqJ-ESDLNoE7otkIzamFskCA
This decodes to:
- Version:
v2 - Purpose:
public(public-key digital signature) - Payload:
{"data": "this is a signed message","exp": "2039-01-01T00:00:00+00:00"}
- Signature (hex-encoded):
d600bbfa3096b0dde6bf8b89699c59a746ed2c981cc95c0bfacbc90fb7f8207c86b5e29edc74cb8c761318723532d0aa27e1120cb36813ba2d908cda985b2408
- Public key (hex-encoded):
11324397f535562178d53ff538e49d5a162242970556b4edd950c87c7d86648a
To learn what each version means, please see this page in the documentation.
Using Paseto (in Elixir)
Generating a token
iex> {:ok, pk, sk} = Salty.Sign.Ed25519.keypair()
iex> keypair = {pk, sk}
iex> token = generate_token("v2", "public", "This is a test message", keypair)
"v2.public.VGhpcyBpcyBhIHRlc3QgbWVzc2FnZSe-sJyD2x_fCDGEUKDcvjU9y3jRHxD4iEJ8iQwwfMUq5jUR47J15uPbgyOmBkQCxNDydR0yV1iBR-GPpyE-NQw"
In short, we generate a keypair using libsalty (libsodium elixir bindings) and generate the token using that keypair.
Parsing a token
iex> token = "v2.public.VGhpcyBpcyBhIHRlc3QgbWVzc2FnZSe-sJyD2x_fCDGEUKDcvjU9y3jRHxD4iEJ8iQwwfMUq5jUR47J15uPbgyOmBkQCxNDydR0yV1iBR-GPpyE-NQw"
iex> Paseto.parse_token(token, keypair)
{:ok,
%Paseto.Token{
footer: nil,
payload: "This is a test message",
purpose: "public",
version: "v2"
}}
"""
More info can be found in the
Installation
You need libsodium installed on your machine.
# Installing on FreeBSD
$ cd /usr/ports/security/libsodium/ && make install clean
# Installing on Ubuntu
$ sudo apt install libsodium-dev
# Installing on Fedora
$ dnf install libsodium-devel
# Redhat & Cent OS
$ yum install libsodium-devel
# Installing on OSX
$ brew install libsodium
If available in Hex, the package can be installed
by adding paseto to your list of dependencies in mix.exs:
def deps do
[
{:paseto, "~> 0.2.0"}
]
end