githubEdit

Signed Tokens (JWS)

Sign a Token with HMAC (HS256)

The simplest approach: a shared secret key is used to both sign and verify the token.

<?php

use Jose\Component\Core\AlgorithmManager;
use Jose\Component\Core\JWK;
use Jose\Component\Signature\Algorithm\HS256;
use Jose\Component\Signature\JWSBuilder;
use Jose\Component\Signature\Serializer\CompactSerializer;

require_once 'vendor/autoload.php';

// Create a symmetric key (shared secret)
$jwk = new JWK([
    'kty' => 'oct',
    'k' => base64_encode(random_bytes(32)), // 256-bit key
]);

$algorithmManager = new AlgorithmManager([new HS256()]);
$jwsBuilder = new JWSBuilder($algorithmManager);

$payload = json_encode([
    'iss' => 'https://my-app.example.com',
    'aud' => 'https://api.example.com',
    'sub' => 'user-42',
    'iat' => time(),
    'exp' => time() + 3600,
]);

$jws = $jwsBuilder
    ->create()
    ->withPayload($payload)
    ->addSignature($jwk, ['alg' => 'HS256'])
    ->build();

$token = (new CompactSerializer())->serialize($jws);
// eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL215LWFwcC...

Verify the Token


Sign a Token with RSA (RS256)

RSA keys allow the signer and the verifier to use different keys: a private key to sign, a public key to verify.

Verify with the Public Key


Sign a Token with Elliptic Curve (ES256)

ECDSA keys are smaller and faster than RSA for the same security level.

Verify with the Public Key


Sign a Token with EdDSA (Ed25519)

EdDSA with Ed25519 provides high performance and strong security. Requires the sodium extension.


The JWSLoader combines deserialization, header checking, and signature verification in a single step. This is the recommended approach for loading tokens.

circle-info

After verifying the signature, you should also validate the claims (exp, iss, aud, etc.). See the Claim and Header Validation page.

Last updated

Was this helpful?