paragonie / paserk-php

PHP Implementation of PASERK
Other
12 stars 1 forks source link

PASERK (PHP)

Build Status Latest Stable Version Latest Unstable Version License Downloads

Platform Agnostic SERialized Keys. Requires PHP 7.1 or newer.

PASERK Specification

The PASERK Specification can be found in this repository.

Installing

composer require paragonie/paserk

PASERK Library Versions

Documentation

See this directory for the documentation.

Example: Public-key Encryption

Wrapping

<?php
use ParagonIE\Paseto\Builder;
use ParagonIE\Paseto\Keys\SymmetricKey;
use ParagonIE\Paseto\Protocol\Version4;
use ParagonIE\Paserk\Operations\Key\SealingPublicKey;
use ParagonIE\Paserk\Types\Seal;

$version = new Version4();

// First, you need a sealing keypair.

// $sealingSecret = ParagonIE\Paserk\Operations\Key\SealingSecretKey::generate();
// $sealingPublic = $sealingSecret->getPublicKey();
// var_dump($sealingSecret->encode(), $sealingPublic->encode());

$sealingPublic = SealingPublicKey::fromEncodedString(
    "vdd1m2Eri8ggYYR5YtnmEninoiCxH1eguGNKe4pes3g",
    $version
);
$sealer = new Seal($sealingPublic);

// Generate a random one-time key, which will be encrypted with the public key:
$key = SymmetricKey::generate($version);

// Seal means "public key encryption":
$paserk = $sealer->encode($key);

// Now let's associate this PASERK with a PASETO that uses the local key:
$paseto = Builder::getLocal($key, $version)
    ->with('test', 'readme')
    ->withExpiration(
        (new DateTime('NOW'))
            ->add(new DateInterval('P01D'))
    )
    ->withFooterArray(['kid' => $sealer->id($key)])
    ->toString();

var_dump($paserk, $paseto);

Unwrapping

<?php
use ParagonIE\Paseto\Protocol\Version4;
use ParagonIE\Paserk\Operations\Key\SealingSecretKey;
use ParagonIE\Paserk\Types\Lid;
use ParagonIE\Paserk\Types\Seal;
use ParagonIE\Paseto\Parser as PasetoParser;
use ParagonIE\Paseto\ProtocolCollection;

$version = new Version4();

// From previous example:
$paserk = "k4.seal.F2qE4x0JfqT7JYhOB7S12SikvLaRuEpxRkgxxHfh4hVpE1JfwIDnreuhs9v5gjoBl3WTVjdIz6NkwQdqRoS2EDc3yGvdf_Da4K1xUSJ8IVTn4HQeol5ruYwjQlA_Ph4N";
$paseto = "v4.local.hYG-BfpTTM3bb-xZ-q5-w77XGayS4WA8kA5R5ZL85u3nzgrWba5NdqgIouFn71CJyGAff1eloirzz3sWRdVXnDeSIYxXDIerNkbLI5ALn24JehhSLKrv8R2-yhfo_XZF9XEASXtwrOyMNjeEAan5kqO6Dg.eyJraWQiOiJrNC5saWQueDAycGJDRmhxU1Q4endnbEJyR3VqWE9LYU5kRkJjY1dsTFFRN0pzcGlZM18ifQ";

// Keys for unsealing:
$sealingSecret = SealingSecretKey::fromEncodedString(
    "j043XiZTuGLleB0kAy8f3Tz-lEePK_ynEWPp4OyB-lS913WbYSuLyCBhhHli2eYSeKeiILEfV6C4Y0p7il6zeA",
    $version
);
$sealingPublic = $sealingSecret->getPublicKey();

// Unwrap the sytmmetric key for `v4.local.` tokens.
$sealer = new Seal($sealingPublic, $sealingSecret);
$unwrapped = $sealer->decode($paserk);

// Parse the PASETO
$parsed = PasetoParser::getLocal($unwrapped, ProtocolCollection::v4())
    ->parse($paseto);

// Get the claims from the parsed and validated token:
var_dump($parsed->getClaims());
/*
array(2) {
  ["test"]=>
  string(6) "readme"
  ["exp"]=>
  string(25) "2038-01-19T03:14:08+00:00"
}
*/

// Observe the Key ID is the same as the value stored in the footer.
var_dump(Lid::encode($version, $paserk));
var_dump($parsed->getFooterArray()['kid']);
/*
string(51) "k4.lid.x02pbCFhqST8zwglBrGujXOKaNdFBccWlLQQ7JspiY3_"
string(51) "k4.lid.x02pbCFhqST8zwglBrGujXOKaNdFBccWlLQQ7JspiY3_"
*/

PASERK Feature Coverage