How to create a valid JWT in PHP using RSA256

I have been having similar difficulties to this question. I need to create a JWT in php. I have the following code:

define('RSA_PRIVATE', 'MIICXAIB......EWxOf9o=');

$payload = json_encode([
    'sub' => 'username',
    'email' => '[email protected]',
    'given_name' => 'John',
    'family_name' => 'Example',
    'iat' => time(),
    'nonce' => '12345'

$header = json_encode([
    'typ' => 'JWT',
    'alg' => 'RS256'

$base64UrlHeader = base64UrlEncode($header);
$base64UrlPayload = base64UrlEncode($payload);
$signature = hash_hmac('sha256', "$base64UrlHeader.$base64UrlPayload", RSA_PRIVATE, true);                                

$base64UrlSignature = base64UrlEncode($signature);
$jwt = "$base64UrlHeader.$base64UrlPayload.$base64UrlSignature";


function base64UrlEncode($text)
    return str_replace(
        ['+', '/', '='],
        ['-', '_', ''],

Whenever I attempt to validate with the third party that needs my JWT it comes back with a message telling me

Signature validation failed: rsa signature did not match

When I attempt to validate using the JWT debugger, it too says it is invalid.

Am I missing something here? Like the previous question I have only ever seen examples where people are using small secrets and not private RSA keys.


  • Following the answer by @Michal Trojanowski I went on to use openssl_sign. However this did not work when I had the key as a variable in my code. Instead, following the example on the php manual I managed to get it to work using the following adjustment:

    $private_key = openssl_pkey_get_private("file:///");
    $base64UrlSignature = zd_base64UrlEncode($signature);
    $jwt = "$base64UrlHeader.$base64UrlPayload.$base64UrlSignature";