php-jwt

Simple and Secure JWT Signer/Verifier

Introduction

This is small and secure JSON Web Token implementation. It only supports the following signatures types:

These seem to be the most widely deployed JWT signature algorithms. The library does NOT support encryption/decryption. Needless to say, this library is NOT fully compliant with the JWT specification!

Why?

Quite a number of JWT implementations exist for PHP, varying in quality. However, JWT can be insecure, so it is very important to get things right from a security perspective. This means implementing the absolute minimum to support JWT, in a secure way. Simplicity and security is more important than fully supporting the specification(s).

How?

A secure JWT library for generating and verifying JSON Web Tokens:

Requirements

On modern PHP versions only paragonie/constant_time_encoding is a dependency, on older versions a number of polyfills are used. See composer.json.

Use

Currently php-jwt is not hosted on Packagist. It will be added there after the 1.0 release. In the meantime in your composer.json:

"repositories": [
    {
        "type": "vcs",
        "url": "https://git.tuxed.net/fkooman/php-jwt"
    },
    ...
],
 
"require": {
    "fkooman/jwt": "^0.3",
    ...
},

Keys

RS256 (RSA)

$ openssl genrsa --out rsa.key 2048
$ openssl rsa -in rsa.key -pubout -out rsa.pub

The RSA key MUST have at least 2048 bits. This will generate a private key in rsa.key and the public key in rsa.pub. Those files can be used with PublicKey and PrivateKey.

To inspect a public key:

$ openssl rsa -pubin -in rsa.pub -noout -text

HS256 (HMAC)

Some helper methods are introduced to help you with generating, loading and saving keys. Do NOT use any other means to generate keys!

<?php
 
// generating and saving a key
$secretKey = \fkooman\Jwt\Keys\HS256\SecretKey::generate();
$encodedString = $secretKey->encode();
 
// loading a key
$secretKey = \fkooman\Jwt\Keys\HS256\SecretKey::fromEncodedString($encodedString);

EdDSA (Ed25519)

<?php
 
// generating and saving a key
$secretKey = \fkooman\Jwt\Keys\EdDSA\SecretKey::generate();
$encodedString = $secretKey->encode();
 
// loading a key
$secretKey = \fkooman\Jwt\Keys\EdDSA\SecretKey::fromEncodedString($encodedString);

The public key can be obtained from the secret key by calling the getPublicKey method on the SecretKey object.

API

RS256

<?php
 
$r = new \fkooman\Jwt\RS256(
    \fkooman\Jwt\Keys\RS256\PublicKey::load('rsa.pub'),
    \fkooman\Jwt\Keys\RS256\PrivateKey::load('rsa.key')
);
$jwtStr = $r->encode(['foo' => 'bar']);
var_dump($r->decode($jwtStr));

The PrivateKey parameter is optional. Do not specify it if you only want to verify JWTs. Of course, you need to specify it when you want to sign a JWT.

HS256

<?php
 
$h = new \fkooman\Jwt\HS256(
    \fkooman\Jwt\Keys\HS256\SecretKey::fromEncodedString(
        '5SBq2gMQFsy6ToGH0SS8CLFPCGxxFl8uohZUooCq5ps'
    )
);
$jwtStr = $h->encode(['foo' => 'bar']);
var_dump($h->decode($jwtStr));

EdDSA (Ed25519)

<?php
 
$secretKey = \fkooman\Jwt\Keys\EdDSA\SecretKey::fromEncodedString(
    'yvo12M7L4puipaUwuuDz_1SMDLz7VPcgcny-OkOHnIEamcDtjH31m6Xlw6a9Ib5dp5A-vHMdzIhUQxUMreqxPg'
);
$publicKey = $secretKey->getPublicKey();
 
$r = new \fkooman\Jwt\EdDSA(
    $publicKey,
    $secretKey
);
$jwtStr = $r->encode(['foo' => 'bar']);
var_dump($r->decode($jwtStr));

The SecretKey parameter is optional. Do not specify it if you only want to verify JWTs. Of course, you need to specify it when you want to sign a JWT.