JWE/JWT authentication with PHP

901 Views Asked by At

Last week we started to work with a new API of a provider. For authentication they request a JWE in the header of an https request.

We have no experience with JWE, then we started to look information about it, to devolope it with PHP.

After many tested and thanks to DinoChiesa online JWT Decoder (https://dinochiesa.github.io/jwt/), we developed a function to make it, but there're something was wrong yet. At the end Dino Chiesa helped us to fix issues and the function below now is working.

<?php 
    require_once("auth/key.php");
    include 'vendor/autoload.php';
    use phpseclib3\Crypt\PublicKeyLoader;  
    
    function jwe (){
        global $payloadAuth; //put here payload that you have to use

        /**************************************************/
        /********************HEADER************************/
        /**************************************************/
        // base64 encodes the header json
        $arr = array('enc' => 'A256GCM', 'alg' => 'RSA-OAEP');
        $arr2 = json_encode($arr);
        $encoded_header=base64url_encode($arr2);     

        /**************************************************/
        /********************JWE KEY***********************/
        /**************************************************/
        $CEK=openssl_random_pseudo_bytes(32);    
        $encoded_EncCEK = base64url_encode(rsaEncryptionOaepSha256($publicKey, $CEK));

        /**************************************************/
        /********************VECTOR************************/
        /**************************************************/
        $iv = openssl_random_pseudo_bytes(12);
        $encoded_iv = base64url_encode($iv);
        
        /**************************************************/
        /********************CYPHERTEXT********************/
        $cipher = "aes-256-gcm";
        $option=1;    
        $aad=$encoded_header;

        $ciphertext=openssl_encrypt($payloadAuth, $cipher, $CEK, $option, $iv, $tag, $aad);
        $encoded_ciphertext=base64url_encode($ciphertext);
        
        /**************************************************/
        /********************TAG***************************/
        /**************************************************/
        $encoded_tag=base64url_encode($tag);
    
        /**************************************************/
        /********************FIN***************************/
        /**************************************************/

        return $encoded_header . '.' . $encoded_EncCEK . '.' . $encoded_iv . '.' . $encoded_ciphertext . '.' . $encoded_tag;

    }
  
    function base64url_encode($data) {
        return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
      }

    function rsaEncryptionOaepSha256($publicKey, $plaintext) {
        global $publicKey;       

        $rsa = PublicKeyLoader::load($publicKey)->withHash('sha1')->withMGFHash('sha1');
        return $rsa->encrypt($plaintext);
    }    

?>

Could someone explain how would change the code if "enc"="A256CBC-HS512" and "alg"="RSA-OAEP-256"?

Thanks and regards, Luis

I expect that people who work with PHP can find year a completee solution for JWE authentication.

1

There are 1 best solutions below

0
On

I'd suggest using web-token/jwt-framework instead of trying to create your own builder/parser functions, as these things can get very tricky!