Search code examples
javascriptphpencryptionjwtjwe

Is it Possible to Encrypt a JWT token in Php And Decrypt in Javascript?


I am Currently using two libraries for JWT . First one for server side

jose php Library

and the second one for client side

jose js library

I am creating a token based login system . All i want is to create a token at server side and after encrypting with JWE(JSON WEB ENCRYPTION) return that token to client and save to html5 local storage .

issue is to decrypt encrypted token in javascript JOSE Library


Solution

  • Because a JWE is an standard format, then there is no problem to issue JWE from a platform (PHP, Java, JS...) and read it with another one.

    The only problem here is that

    • you have to find a library for each platform you want to use.
    • these libraries must have common algorithms

    I do not know nov/jose-php but the code review and the tests I performed show me it supports some well-known algorithms (RSA1_5/RSA-OAEP/dir for key encryption and A128CBC-HS256/A256CBC-HS512 for content encryption).

    If you use RSA-OAEP and A128CBC-HS256 or A256CBC-HS512 on your project, then you should be able to encrypt on one side and decrypt on the other side.

    If you want to use other algorithms on PHP such as AxxxKW or AxxxGCM, you should have a look on the spomky-labs/jose PHP library which supports dozen of algorithms, compression and more.

    You should also look at jwt.io which lists a lot of Jose implementations on several platforms.

    Edit

    Private/Public RSA Key Converter

    With spomky-labs/jose:

    <?php
    use Jose\Factory\JWKFactory;
    $key = JWKFactory::createFromKeyFile('/path/to/your/key.pem');
    // The variable $key is a JWKInterface instance that can be easily converted into a JSON object: json_encode($key)
    

    In pure PHP:

    <?php
    $res = openssl_pkey_get_private($data);
    if (false === $res) {
        $res = openssl_pkey_get_public($data);
    }
    // Verify here that $res is not false.
    
    
    $details = openssl_pkey_get_details($res);
    //Verify here that the array $details has a key 'rsa' (could be 'ec')
    
    $components = [
        'n'  => 'n',
        'e'  => 'e',
        'd'  => 'd',
        'p'  => 'p',
        'q'  => 'q',
        'dp' => 'dmp1',
        'dq' => 'dmq1',
        'qi' => 'iqmp',
    ];
    
    $key = ['kty' => 'RSA'];
    foreach ($details['rsa'] as $key => $value) {
        if (in_array($key, $components)) {
            $key[array_search($key, $components)] = Base64Url::encode($value); // Base64 Url Safe encoding. See https://github.com/Spomky-Labs/base64url
        }
    }
    // The variable $key is an array with the expected information