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:

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 secret key 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

    <?php
 
    $secretKey = \fkooman\Jwt\Keys\EdDSA\SecretKey::fromEncodedString('yvo12M7L4puipaUwuuDz_1SMDLz7VPcgcny-OkOHnIEamcDtjH31m6Xlw6a9Ib5dp5A-vHMdzIhUQxUMreqxPg');
    $r = new \fkooman\Jwt\EdDSA(
        $secretKey->getPublicKey(),
        $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.