Search code examples
jwtopensslbase64jwt.io

What does "secret base64 encoded" on jwt.io mean and how would I simulate it with `openssl dgst`


I try to get the same output from jwt.io and openssl. As long as I do not mark "secret base64 encoded", I can take the part before the signature, run it through

echo -n "pasted data from jwt.io" | \
  | openssl dgst -binary -sha512 -hmac abc \
  | openssl enc -base64 -A;

and I get the same signature back from openssl as jwt.io is showing (using HS512!).

If I click the "secret base64 encoded", obviously the signature changes on jwt.io. Now I encode the secret "abc" with base64 to get "YWJj" and use this as the secret for openssl as in

echo -n "pasted data from jwt.io" | \
  | openssl dgst -binary -sha512 -hmac YWJj \
  | openssl enc -base64 -A;

This does not create the same signature, so I am likely misunderstanding this checkbox. What exactly does it and how would I need to call openssl to simulate it?

(I know there is a difference between base64 and base64 urlencode, but this should not make a difference for the encoding of "abc".)


Solution

  • The option secret base64 encoded on https://jwt.io means that the secret you paste into the input field is base64 encoded an therefore needs to be decoded before it is applied. Then jwt.io makes this extra step to decode the secret first.

    jwt.io indeed produces the same hash in both cases:

    • secret = 'abc' and secret base64 encoded= no or
    • secret = 'YWJj' and secret base64 encoded = yes,

    so that part works fine and behaves as expected.

    But your OpenSSL command lines are exactly the same, only the keys are different. OpenSSL doesn't know about your encoding and treats them just as different keys, therefore producing different results.

    I'm not aware of any command line switch that would tell OpenSSL to treat the key as an encoded key.