I am trying to decode a STIR/SHAKEN HS256 JSON Web Token.
I tried with the Jose .NET library:
string token = "eyJhbGciOiJFUzI1NiIsInBwdCI6InNoYWtlbiIsInR5cCI6InBhc3Nwb3J0IiwieDV1IjoiaHR0cHM6Ly9jci5zYW5zYXkuY29tL1RlY2hub2xvZ3lfSW5ub3ZhdGlvbl9MYWJfNTk5SiJ9.eyJhdHRlc3QiOiJCIiwiZGVzdCI6eyJ0biI6WyIxNDc5MjM5OTcwMyJdfSwiaWF0IjoxNjU5NTIxNDU5LCJvcmlnIjp7InRuIjoiMTQ2OTUwMTYwNzAifSwib3JpZ2lkIjoiOTIzNDIxOTgtMTMxNC0xMWVkLWExM2QtYmRjMWMxZDI4ODg4In0.8RF_eaVKeGGyjet4lujwPz0J_XBdtwkSKrnrOq7-pA6ODtJPD1parLgimEpDUyzSravtTaxuACxBz4yrKtMZgw";
string x = Jose.JWT.Decode(token, Nothing, JweAlgorithm.PBES2_HS256_A128KW);
It gives an error
Jose.InvalidAlgorithmException: 'The algorithm type passed to the Decode method did not match the algorithm type in the header.'
Trying the token above on https://jwt.io/ Debugger works and returns the following:
HEADER:ALGORITHM & TOKEN TYPE
{
"alg": "ES256",
"ppt": "shaken",
"typ": "passport",
"x5u": "https://cr.sansay.com/Technology_Innovation_Lab_599J"
}
PAYLOAD:DATA
{
"attest": "B",
"dest": {
"tn": [
"14792399703"
]
},
"iat": 1659521459,
"orig": {
"tn": "14695016070"
},
"origid": "92342198-1314-11ed-a13d-bdc1c1d28888"
}
CodePudding user response:
The token is actually signed with the ES256 algorithm, not HS256.
The key is provided in the URL that is given in the header in the X5U
-claim, which is a URL pointing to a X.509 certificate.
For the demo below and to keep it simple, I saved the certificate to a file name x509.pem
.
Here is a simple demo:
using Jose;
using System;
using System.Security.Cryptography.X509Certificates;
namespace JoseJWTES256X509Test
{
class Program
{
static void Main(string[] args)
{
string token = "eyJhbGciOiJFUzI1NiIsInBwdCI6InNoYWtlbiIsInR5cCI6InBhc3Nwb3J0IiwieDV1IjoiaHR0cHM6Ly9jci5zYW5zYXkuY29tL1RlY2hub2xvZ3lfSW5ub3ZhdGlvbl9MYWJfNTk5SiJ9.eyJhdHRlc3QiOiJCIiwiZGVzdCI6eyJ0biI6WyIxNDc5MjM5OTcwMyJdfSwiaWF0IjoxNjU5NTIxNDU5LCJvcmlnIjp7InRuIjoiMTQ2OTUwMTYwNzAifSwib3JpZ2lkIjoiOTIzNDIxOTgtMTMxNC0xMWVkLWExM2QtYmRjMWMxZDI4ODg4In0.8RF_eaVKeGGyjet4lujwPz0J_XBdtwkSKrnrOq7-pA6ODtJPD1parLgimEpDUyzSravtTaxuACxBz4yrKtMZgw";
var publicKey = new X509Certificate2("x509.pem").GetECDsaPublicKey();
string payload = Jose.JWT.Decode(token, publicKey, JwsAlgorithm.ES256);
Console.WriteLine(payload);
}
}
}
As a result the token will be verified and the payload will be printed. In case of a failed verification, the Decode
-function would throw an exception.
As a side note: the Decode
-function actually verifies the signature before decoding, and that's for what it needs the key. For the actual decoding, no key is needed because the payload is just Bese64Url encoded. That's why https://jwt.io can also decode the token without knowing the key.