1

My goal is to create an unencrypted signed token. I'm generating my JWT like this :

private const string C_ISSUER_SIGNINGKEY = "kXp2s5v8y/B?D(G+KbPeShVmYq3t6w9z";
private const JweAlgorithm JWE_ALGO = JweAlgorithm.DIR;
private const JweEncryption JWE_ENCR = JweEncryption.A128CBC_HS256;

public string GenerateToken(Dictionary<string, object> aPayload, TimeSpan aExpirationTime)
{
   var aNowMs = DateTime.Now.ToUniversalTime().Subtract(
                    new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)
                    ).TotalMilliseconds;
   if (aExpirationTime.TotalMilliseconds > 0)
   {
       var lExp = aNowMs + aExpirationTime.TotalMilliseconds;
       aPayload.Add("exp", lExp);
   }
   var aSecretKey = Encoding.UTF8.GetBytes(C_ISSUER_SIGNINGKEY);
   var aToken = JWT.Encode(aPayload, aSecretKey, JWE_ALGO, JWE_ENCR);
   return aToken;
}

When using this, I get a token like this :

var lPayLoad = new Dictionary<string, object>()
{
    { "emailAddress", "peter@email.com" },
    { "password", "password" }
};
var lToken = lEncryptor.GenerateToken(lPayLoad, new TimeSpan(50,50,50,50));

I'll then get a token like this :eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..4lvBJr_Q0X_hj5OL5rdMsA.d0S--Vdm0JDkjYcN1Djnx4KV3DbehzwkHlvDKlFQuAk.DVS5O8zmJr2l1axenk2Fgw

(Note, that the payload section is empty in the token)

When I try to decode this (via jwt.Io, or any other tool), I can't validate the signer, nor am I able to get the payload.

What on earth am I doing wrong?

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
WynDiesel
  • 1,104
  • 7
  • 38
  • that's indeed an invalid token with no payload, but it's not really clear what your goal is here. Some parts of your code look like you want to create an encrypted token (JWE) but you end up with an invalid JWS (signed token) which has also an invalid `alg`claim in the header. – jps Jan 15 '21 at 14:13
  • @jps. Thanks for your comment. My goal is to make an unencrypted, signed token. I was under the impression JWT.Encode only signs it, not encrypt it. Am I incorrect on this assumption? – WynDiesel Jan 15 '21 at 14:15
  • 1
    JWT.Encode seems to sign it, that's true, but I wonder which algorithm was actually used, as the given `JWE_ALGO = JweAlgorithm.DIR;` makes no sense for a signed token. It usually should be something like e.g. `HS256`, or `RS256. Which library are you using here? – jps Jan 15 '21 at 14:19
  • @jps, that was it! string tokenSigned = JWT.Encode(aPayload, aSecretKey, JwsAlgorithm.HS256); solved my issue. I'm using jose, btw. If you want to add this as an answer, I'll accept it. – WynDiesel Jan 15 '21 at 14:24
  • @jps. I'm using jose-jwt. – WynDiesel Jan 15 '21 at 14:32

1 Answers1

2

In your code you're using a wrong algorithm type for a signed token (JWS).

JweAlgorithm JWE_ALGO = JweAlgorithm.DIR

var aToken = JWT.Encode(aPayload, aSecretKey, JWE_ALGO, JWE_ENCR);

and also the JWE_ENCR parameter is wrong in this context.

For a JWS created with jose-jwt you need to choose a proper signing algorithm, e.g.:

 JwsAlgorithm.HS256

or

 JwsAlgorithm.HS512
 JwsAlgorithm.RS256
 JwsAlgorithm.RS512
 JwsAlgorithm.ES256

etc. (Reference)

If you change the line to:

JWT.Encode(aPayload, aSecretKey, JwsAlgorithm.HS256);

It should work fine.

jps
  • 20,041
  • 15
  • 75
  • 79