Skip to content
Advertisement

Understanding RS256 and SHA256 during JWT Token creation

I am creating a JWT Token using a private key in PHP. For this I am using the OpenSSL library. Before anything I will share my code :

PHP

JavaScript

So, this JWT Token will be used for authentication in a server which I am trying to hit. But I get the response from the external server as a Bad Request, problem happening in my JWT token creation.

With same credentials, I tried in javascript using the library jsrsasign and it then gives me the correct response.

JAVASCRIPT

JavaScript

One difference which I can clearly see is that for the signature generation function in the php end I am passing sha256 as the algorithm and in the JavaScript RS256 is passed.

I read about how sha256 is just a hashing algorithm and RS256 is used for encoding, but in all the libraries I found in php, they were internally passing sha256 only in the openssl_sign function. And openssl_sign doesn’t have RS256 as an algorithm parameter.

So, firstly is there anywhere where I went wrong.

Secondly, is there a way we can generate a signature using RS256 in php.

PS : I am looking for solution in php.

Advertisement

Answer

  • The return-value of KJUR.jws.JWS.sign consists of three portions separated by a dot. The first part is the Base64url-encoded JSON-string sHeader, the second part is the Base64url-encoded JSON-string sPayload and the third part is the Base64url-encoded signature. The data to be signed consist of the first two portions including the dot separating the two portions. RS256 means that SHA256 and RSA with RSASSA-PKCS1-v1_5 padding is used for the signature. This can also be easily verified online, e.g. here, whereby SHA256withRSA is to be selected as the algorithm.

  • openssl_sign also uses RSA with RSASSA-PKCS1-v1_5 padding and therefore creates the same signature with SHA256, assuming the same key and the same data to be signed are applied.

  • jsrsasign uses Base64 url-encoding (RFC4648, sect. 5), while PHP (or more precisely the base64_encode-method) uses standard Base64-encoding (RFC4648, sect. 4), which most likely is one cause of the issue. This means that the encoding in the current PHP-code must be changed to Base64url, e.g. here.

  • Of course, the underlying JSON-strings in the PHP-code ($header, $payload and $token) must also be identical to their counterparts in the JavaScript-code, otherwise the signature will differ. Since the PHP-code is incomplete, this cannot be checked and could be another cause of the problem.

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement