PHP Classes

PHP PASeTo: Encrypt and decrypt data with PaSeTO protocol

Recommend this page to a friend!
     
  Info   Example   View files Files   Install with Composer Install with Composer   Download Download   Reputation   Support forum   Blog    
Ratings Unique User Downloads Download Rankings
Not yet rated by the usersTotal: 69 All time: 10,305 This week: 571Up
Version License PHP version Categories
paseto 1.0.0MIT/X Consortium ...5PHP 5, Cryptography
Description 

Author

This package can be used to Sign, encrypt and decrypt data with Platform-Agnostic Security Tokens protocol.

It can perform several data encryption operations using secure tokens defined using the PASeTo protocol. Currently it can:

- Create a private and public key pair
- Create a shared key for symmetric encryption
- Sign data with a shared key
- Build and verify a secure token with a shared key
- Decode a token with a shared key

Innovation Award
PHP Programming Innovation award nominee
February 2020
Number 13
PASETO (Platform-Agnostic SEcurity TOkens) is a more secure approach sign, encrypt and decrypt data designed by Scott Arciszewski as an alternative to using JSON Web Tokens .

This package provides an PHP implementation of PASETO.

Manuel Lemos
Picture of Scott Arciszewski
  Performance   Level  
Name: Scott Arciszewski <contact>
Classes: 37 packages by
Country: United States United States
Age: ???
All time rank: 1173170 in United States United States
Week rank: 44 Up6 in United States United States Up
Innovation award
Innovation award
Nominee: 28x

Winner: 1x

Example

How to use the PHP library

The first thing you should know about Paseto is that it tries to accomplish type-safety by wrapping cryptographic keys inside of objects. For example:

<?php
use ParagonIE\Paseto\Keys\{
    AsymmetricSecretKey,
    SymmetricKey    
};

$privateKey = new AsymmetricSecretKey(sodium_crypto_sign_keypair());
$publicKey = $privateKey->getPublicKey();

$sharedKey = new SymmetricKey(random_bytes(32));

You can access the key's internal strings by invoking $key->raw().

No version of the protocol will let you misuse a key by accident. This will generate a TypeError:

<?php
use ParagonIE\Paseto\Protocol\Version2;
use ParagonIE\Paseto\Keys\SymmetricKey;

/
 * @var SymmetricKey $sharedKey
 */
$token = Version2::sign('some arbitrary data', $sharedKey);

Building and Verifying Pasetos

The simplest use-case is to use shared-key authentication to achieve tamper-resistant tokens:

<?php
use ParagonIE\Paseto\Builder;
use ParagonIE\Paseto\Purpose;
use ParagonIE\Paseto\Keys\SymmetricKey;
use ParagonIE\Paseto\Protocol\Version2;

/
 * @var SymmetricKey $sharedKey
 */
$token = Builder::getLocal($sharedKey, new Version2());

$token = (new Builder())
    ->setKey($sharedKey)
    ->setVersion(new Version2())
    ->setPurpose(Purpose::local())
    // Set it to expire in one day
    ->setExpiration(
        (new DateTime())->add(new DateInterval('P01D'))
    )
    // Store arbitrary data
    ->setClaims([
        'example' => 'Hello world',
        'security' => 'Now as easy as PIE'
    ]);
echo $token; // Converts automatically to a string

Decoding tokens

First, you need to define your Parser rules.

  • Which versions of the protocol do you wish to allow? If you're only using v2 in your app, you should specify this.
<?php
use ParagonIE\Paseto\Exception\PasetoException;
use ParagonIE\Paseto\Keys\SymmetricKey;
use ParagonIE\Paseto\Parser;
use ParagonIE\Paseto\Purpose;
use ParagonIE\Paseto\Rules\{
    IssuedBy,
    NotExpired
};
use ParagonIE\Paseto\ProtocolCollection;

/
 * @var string $providedToken
 * @var SymmetricKey $sharedKey
 */
$parser = Parser::getLocal($sharedKey, ProtocolCollection::v2());
// This is the same as:
$parser = (new Parser())
    ->setKey($sharedKey)
    // Adding rules to be checked against the token
    ->addRule(new NotExpired)
    ->addRule(new IssuedBy('issuer defined during creation'))
    ->setPurpose(Purpose::local())
    // Only allow version 2
    ->setAllowedVersions(ProtocolCollection::v2());

try {
    $token = $parser->parse($providedToken);
} catch (PasetoException $ex) {
    /Handle invalid token cases here./
}
var_dump($token instanceof \ParagonIE\Paseto\JsonToken);
// bool(true)

Using the Protocol Directly

Unlike JWT, we don't force you to use JSON. You can store arbitrary binary data in a Paseto, by invoking the Protocol classes directly. This is an advanced usage, of course.

<?php
use ParagonIE\Paseto\Keys\SymmetricKey;
use ParagonIE\Paseto\Protocol\{Version1, Version2};

$key = new SymmetricKey('YELLOW SUBMARINE, BLACK WIZARDRY');
$message = 'This is a signed, non-JSON message.';
$footer = 'key-id:gandalf0';

# Version 1:
$v1Token = Version1::encrypt($message, $key);
var_dump((string) $v1Token);
// string(163) "v1.local.B0VgDOyAtKza1ZCsPzlwQZGTfrpbo1vgzUwCvyxLiSM-gw3TC_KtMqX8woy8BuuE9-pRQNmnTGAru5OmVLzPDnDBHXbd8Sz5rssiTz5TZKLqSyYHsgBzfc53PqsTxLvw09QAy5KBSpKErPX_EfF0Od6-Ig"
var_dump(Version1::decrypt($v1Token, $key));
// string(35) "This is a signed, non-JSON message."

$v1Token = Version1::encrypt($message, $key, $footer);
var_dump((string) $v1Token);
// string(184) "v1.local.vu2ZV_apVDvIhExdenX6rm5w13E3LraRbgN9tabtspSR6KQQt5XdGY5Hho64VRj6Pa6gd-5w5XwmRZbnrxfSVYyvXrVfyDJC7pqQDgae8-MHDg5rZul7kFiH6ExXWx-1hJupWSkRnfQy168PzwS14xiTgw.a2V5LWlkOmdhbmRhbGYw"
var_dump(Version1::decrypt($v1Token, $key, $footer));
// string(35) "This is a signed, non-JSON message."

# Version 2:
$v2Token = Version2::encrypt($message, $key);
var_dump((string) $v2Token);
// string(109) "v2.local.0qOisotef_M2W1gK0b6SiUrO4fkPb24Se0eNJAkALmDvS3IlVu-72birx07hIqU4MYtrCrTJTTElYaWxOyz5Wx8wXh8cQUOF6wOo"
var_dump(Version2::decrypt($v2Token, $key));
// string(35) "This is a signed, non-JSON message."

$v2Token = Version2::encrypt($message, $key, $footer);
var_dump((string) $v2Token);
// string(130) "v2.local.b6ClQBYz-s8k7CC-dEYz2sf3zQFqES4xNUP6K-lzQTRnxVlZFxNnT5I6ouSwYe1d-t9OTnjM9d46MEt__GJvHbNO1wwIfnf1Ear-.a2V5LWlkOmdhbmRhbGYw"
var_dump(Version2::decrypt($v2Token, $key, $footer));
// string(35) "This is a signed, non-JSON message."

Details

PASETO: Platform-Agnostic Security Tokens

Build Status Latest Stable Version Latest Unstable Version License Downloads

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

What follows is a reference implementation. Requires PHP 7 or newer.

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):
    400c48a557be10254d235cf8c506e6fea418a26c93de1f05b55f1bc64cfca412
    56913f1fec7b653a96eba0f0c46542a8a7fbda825ca9efa0b3632dfbe5c1e628
    25bc7b5082915d0b7e5bb81930f25cca9076964c33513a39aa105b6ee06914af
    581ad1dc881b1486b4024b9417
    
    * Nonce: `400c48a557be10254d235cf8c506e6fea418a26c93de1f05` * Authentication tag: `6914af581ad1dc881b1486b4024b9417`
  • 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.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):
    d600bbfa3096b0dde6bf8b89699c59a746ed2c981cc95c0bfacbc90fb7f8207c
    86b5e29edc74cb8c761318723532d0aa27e1120cb36813ba2d908cda985b2408
    
  • Public key (hex-encoded):
    11324397f535562178d53ff538e49d5a162242970556b4edd950c87c7d86648a
    

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 encryption (symmetric-key, AEAD)
  • `public` -- public-key digital signatures (asymmetric-key)

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.

How to Use this Library

See the documentation.

The section dedicated to this PHP implementation may be more relevant.

Other Implementations

The curation of other implementations has been moved to paseto.io. See https://github.com/paragonie/paseto-io for the website source code.

Support Contracts

If your company uses this library in their products or services, you may be interested in purchasing a support contract from Paragon Initiative Enterprises.


  Files folder image Files (69)  
File Role Description
Files folder imagedocs (1 file, 4 directories)
Files folder imagesrc (11 files, 6 directories)
Files folder imagetests (9 files)
Accessible without login Plain text file .travis.yml Data Auxiliary data
Accessible without login Plain text file composer.json Data Auxiliary data
Accessible without login Plain text file LICENSE Lic. License text
Accessible without login Plain text file phpunit.xml.dist Data Auxiliary data
Accessible without login Plain text file psalm.xml Data Auxiliary data
Accessible without login Plain text file README.md Doc. Documentation

  Files folder image Files (69)  /  docs  
File Role Description
Files folder image01-Protocol-Versions (4 files)
Files folder image02-PHP-Library (1 file)
Files folder image03-Implementation-Guide (3 files)
Files folder imageRFC (6 files)
  Accessible without login Plain text file README.md Doc. Documentation

  Files folder image Files (69)  /  docs  /  01-Protocol-Versions  
File Role Description
  Accessible without login Plain text file Common.md Data Auxiliary data
  Accessible without login Plain text file README.md Doc. Documentation
  Accessible without login Plain text file Version1.md Data Auxiliary data
  Accessible without login Plain text file Version2.md Data Auxiliary data

  Files folder image Files (69)  /  docs  /  02-PHP-Library  
File Role Description
  Accessible without login Plain text file README.md Example Example script

  Files folder image Files (69)  /  docs  /  03-Implementation-Guide  
File Role Description
  Accessible without login Plain text file 01-Payload-Processing.md Data Auxiliary data
  Accessible without login Plain text file 02-Validators.md Data Auxiliary data
  Accessible without login Plain text file README.md Doc. Documentation

  Files folder image Files (69)  /  docs  /  RFC  
File Role Description
  Accessible without login Plain text file build.sh Data Auxiliary data
  Accessible without login Plain text file draft-paragon-paseto-rfc-00.txt Doc. Documentation
  Accessible without login Plain text file draft-paragon-paseto-rfc-01.txt Doc. Documentation
  Accessible without login Plain text file GNUmakefile Data Auxiliary data
  Accessible without login Plain text file paseto.md Data Auxiliary data
  Accessible without login Plain text file README.md Doc. Documentation

  Files folder image Files (69)  /  src  
File Role Description
Files folder imageException (8 files)
Files folder imageKeys (3 files, 2 directories)
Files folder imageParsing (2 files)
Files folder imageProtocol (2 files)
Files folder imageRules (6 files)
Files folder imageTraits (1 file)
  Accessible without login Plain text file Builder.php Class Class source
  Accessible without login Plain text file JsonToken.php Class Class source
  Accessible without login Plain text file KeyInterface.php Class Class source
  Accessible without login Plain text file Parser.php Class Class source
  Accessible without login Plain text file ProtocolCollection.php Class Class source
  Accessible without login Plain text file ProtocolInterface.php Class Class source
  Accessible without login Plain text file Purpose.php Class Class source
  Accessible without login Plain text file ReceivingKey.php Class Class source
  Accessible without login Plain text file SendingKey.php Class Class source
  Accessible without login Plain text file Util.php Class Class source
  Accessible without login Plain text file ValidationRuleInterface.php Class Class source

  Files folder image Files (69)  /  src  /  Exception  
File Role Description
  Accessible without login Plain text file EncodingException.php Class Class source
  Accessible without login Plain text file InvalidKeyException.php Class Class source
  Accessible without login Plain text file InvalidPurposeException.php Class Class source
  Accessible without login Plain text file InvalidVersionException.php Class Class source
  Accessible without login Plain text file NotFoundException.php Class Class source
  Accessible without login Plain text file PasetoException.php Class Class source
  Accessible without login Plain text file RuleViolation.php Class Class source
  Accessible without login Plain text file SecurityException.php Class Class source

  Files folder image Files (69)  /  src  /  Keys  
File Role Description
Files folder imageVersion1 (3 files)
Files folder imageVersion2 (3 files)
  Accessible without login Plain text file AsymmetricPublicKey.php Class Class source
  Accessible without login Plain text file AsymmetricSecretKey.php Class Class source
  Accessible without login Plain text file SymmetricKey.php Class Class source

  Files folder image Files (69)  /  src  /  Keys  /  Version1  
File Role Description
  Accessible without login Plain text file AsymmetricPublicKey.php Class Class source
  Accessible without login Plain text file AsymmetricSecretKey.php Class Class source
  Accessible without login Plain text file SymmetricKey.php Class Class source

  Files folder image Files (69)  /  src  /  Keys  /  Version2  
File Role Description
  Accessible without login Plain text file AsymmetricPublicKey.php Class Class source
  Accessible without login Plain text file AsymmetricSecretKey.php Class Class source
  Accessible without login Plain text file SymmetricKey.php Class Class source

  Files folder image Files (69)  /  src  /  Parsing  
File Role Description
  Accessible without login Plain text file Header.php Class Class source
  Accessible without login Plain text file PasetoMessage.php Class Class source

  Files folder image Files (69)  /  src  /  Protocol  
File Role Description
  Accessible without login Plain text file Version1.php Class Class source
  Accessible without login Plain text file Version2.php Class Class source

  Files folder image Files (69)  /  src  /  Rules  
File Role Description
  Accessible without login Plain text file ForAudience.php Class Class source
  Accessible without login Plain text file IdentifiedBy.php Class Class source
  Accessible without login Plain text file IssuedBy.php Class Class source
  Accessible without login Plain text file NotExpired.php Class Class source
  Accessible without login Plain text file Subject.php Class Class source
  Accessible without login Plain text file ValidAt.php Class Class source

  Files folder image Files (69)  /  src  /  Traits  
File Role Description
  Accessible without login Plain text file RegisteredClaims.php Class Class source

  Files folder image Files (69)  /  tests  
File Role Description
  Accessible without login Plain text file JsonTokenTest.php Class Class source
  Accessible without login Plain text file NonceFixer.php Class Class source
  Accessible without login Plain text file ParserTest.php Class Class source
  Accessible without login Plain text file ReadmeTest.php Class Class source
  Accessible without login Plain text file UtilTest.php Class Class source
  Accessible without login Plain text file Version1Test.php Class Class source
  Accessible without login Plain text file Version1VectorTest.php Class Class source
  Accessible without login Plain text file Version2Test.php Class Class source
  Accessible without login Plain text file Version2VectorTest.php Class Class source

The PHP Classes site has supported package installation using the Composer tool since 2013, as you may verify by reading this instructions page.
Install with Composer Install with Composer
 Version Control Unique User Downloads Download Rankings  
 100%
Total:69
This week:0
All time:10,305
This week:571Up