paseto

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 21, 2018 License: MIT Imports: 19 Imported by: 0

README

PASETO: Platform-Agnostic Security Tokens (GO implementation)

License GoDoc Build Status Coverage Status Go Report Card

This is fully compatible GO implementation of PASETO library.

Paseto is everything you love about JOSE (JWT, JWE, JWS) without any of the many design deficits that plague the JOSE standards.

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.lClhzVOuseCWYep44qbA8rmXry66lUupyENijX37_I_z34EiOlfyuwqIIhOjF-e9m2J-Qs17Gs-BpjpLlh3zf-J37n7YGHqMBV6G5xD2aeIKpck6rhfwHpGF38L7ryYuzuUeqmPg8XozSfU4PuPp9o8.UGFyYWdvbiBJbml0aWF0aXZlIEVudGVycHJpc2Vz

This decodes to:

  • Version: v2
  • Purpose: local (shared-key authenticated encryption)
  • Payload (hex-encoded):
    942961cd53aeb1e09661ea78e2a6c0f2b997af2eba954ba9c843628d7dfbfc8f
    f3df81223a57f2bb0a882213a317e7bd9b627e42cd7b1acf81a63a4b961df37f
    e277ee7ed8187a8c055e86e710f669e20aa5c93aae17f01e9185dfc2fbaf262e
    cee51eaa63e0f17a3349f5383ee3e9f68f
    
    • Nonce: 942961cd53aeb1e09661ea78e2a6c0f2b997af2eba954ba9
    • Authentication tag: e51eaa63e0f17a3349f5383ee3e9f68f
  • Decrypted Payload:
    {
      "data": "this is a signed message",
      "exp": "2039-01-01T00:00:00+00:00"
    }
    
    • Key used in this example (hex-encoded):
      707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f  
      
  • Footer:
    Paragon Initiative Enterprises
    
Paseto Example 2
v2.public.eyJkYXRhIjoidGhpcyBpcyBhIHNpZ25lZCBtZXNzYWdlIiwiZXhwaXJlcyI6IjIwMTktMDEtMDFUMDA6MDA6MDArMDA6MDAifcMYjoUaEYXAtzTDwlcOlxdcZWIZp8qZga3jFS8JwdEjEvurZhs6AmTU3bRW5pB9fOQwm43rzmibZXcAkQ4AzQs.UGFyYWdvbiBJbml0aWF0aXZlIEVudGVycHJpc2Vz

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):
    70c623a1468461702dcd30f095c3a5c5d719588669f2a6606b78c54bc2707448
    c4beead986ce809935376d15b9a41f5f390c26e37af39a26d95dc02443803342
    

To learn what each version means, please see this page in the documentation.

JWT

An example JWT (taken from JWT.io) might look like this:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ 

This decodes to:

Header:

{
  "alg": "HS256",
  "typ": "JWT"
}

Body:

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

Signature:

TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

Motivation

As you can see, with JWT, you get to specify an alg header. There are a lot of options to choose from (including none).

There have been ways to exploit JWT libraries by replacing RS256 with HS256 and using the known public key as the HMAC-SHA256 key, thereby allowing arbitrary token forgery.

With Paseto, your options are version and a purpose. There are two possible values for purpose:

  • local -- shared-key authenticated encrypted
  • public -- public-key authentication (a.k.a. digital signatures)

Paseto only allows you to use authenticated modes.

Regardless of the purpose selected, the header (and an optional footer, which is always cleartext but base64url-encoded) is included in the signature or authentication tag.

Documentation

Index

Constants

View Source
const (
	// V1 defines protocol version 1
	V1 = Version("v1")
	// V2 defines protocol version 1
	V2 = Version("v2")
)

Variables

View Source
var (
	// ErrUnsupportedTokenVersion unsupported parser version
	ErrUnsupportedTokenVersion = errors.New("unsupported parser version")
	// ErrUnsupportedTokenType unsupported token type
	ErrUnsupportedTokenType = errors.New("unsupported token type")
	// ErrIncorrectPrivateKeyType incorrect private key type
	ErrIncorrectPrivateKeyType = errors.New("incorrect private key type")
	// ErrIncorrectPublicKeyType incorrect public key type
	ErrIncorrectPublicKeyType = errors.New("incorrect public key type")
	// ErrPublicKeyNotFound public key for this version not found
	ErrPublicKeyNotFound = errors.New("public key for this version not found")
	// ErrIncorrectTokenFormat incorrect token format
	ErrIncorrectTokenFormat = errors.New("incorrect token format")
	// ErrIncorrectTokenHeader incorrect token header
	ErrIncorrectTokenHeader = errors.New("incorrect token header")
	// ErrInvalidTokenAuth invalid token authentication
	ErrInvalidTokenAuth = errors.New("invalid token authentication")
	// ErrInvalidSignature invalid signature
	ErrInvalidSignature = errors.New("invalid signature")
	// ErrDataUnmarshal can't unmarshal token data to the given type of value
	ErrDataUnmarshal = errors.New("can't unmarshal token data to the given type of value")
)

Functions

func GetTokenInfo

func GetTokenInfo(token string) (Version, Purpose, error)

GetTokenInfo returns token version and purpose

func ParseFooter

func ParseFooter(token string, footer interface{}) error

ParseFooter parses footer from token

func WithFooter

func WithFooter(footer interface{}) func(*options)

WithFooter adds footer to the token

Types

type Protocol

type Protocol interface {
	// Encrypt encrypts token with symmetric key
	Encrypt(key []byte, payload interface{}, options ...opsFunc) (string, error)
	// Decrypt decrypts key encrypted with symmetric key
	Decrypt(token string, key []byte, payload interface{}, footer interface{}) error
	// Sign signs token with given private key
	Sign(privateKey crypto.PrivateKey, payload interface{}, options ...opsFunc) (string, error)
	// Verify verifies token with given public key
	Verify(token string, publicKey crypto.PublicKey, value interface{}, footer interface{}) error
}

Protocol defines PASETO tokes protocol

func NewV1

func NewV1() Protocol

NewV1 return V1 implementation on paseto tokens

func NewV2

func NewV2() Protocol

NewV2 return V2 implementation on paseto tokens

type Purpose

type Purpose int

Purpose defines token type

const (
	// LOCAL defines symmetric encrypted token type
	LOCAL Purpose = iota
	// PUBLIC defines asymmetric signed token type
	PUBLIC
)

type Version

type Version string

Version defines token version

func Parse

func Parse(token string, payload interface{}, footer interface{},
	symmetricKey []byte, publicKeys map[Version]crypto.PublicKey) (Version, error)

Parse extracts payload and footer from token. To parse public tokens need to specify v1 and v2 public keys.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL