jwtk/jjwt

Overloaded methods of setSigningKey() behave differently

mipo256 opened this issue · 3 comments

There is an overloaded mehtod - JwtBuilder#setSigningKey. It may accept base64 encoded String, or it may accept byte[]

Here is the implementation in your source:

    @Override
    public JwtParser setSigningKey(byte[] key) {
        Assert.notEmpty(key, "signing key cannot be null or empty.");
        this.keyBytes = key;
        return this;
    }

    @Override
    public JwtParser setSigningKey(String base64EncodedKeyBytes) {
        Assert.hasText(base64EncodedKeyBytes, "signing key cannot be null or empty.");
        this.keyBytes = TextCodec.BASE64.decode(base64EncodedKeyBytes);
        return this;
    }

It seems to me, that in 2nd method, if base64 encoded key is decoded before being set to keyBytes --> keyBytes field is a plain bytes key, i.e. not byte of base64 encoded key. However, it seems not be the case with setSigningKey(byte[] key) method.

Problem:

  1. When I pass just bytes in the UTF-8 unicode encoding to method setSigningKey(byte[] key), then the library complains about signature.

  2. However, if I pass bytes of base64 encoded key into setSigningKey(byte[] key), then the key parsed fine. The is clear contriversion in the API, because setSigningKey(byte[] key) works with base64 encoded bytes, while setSigningKey(String base64EncodedKeyBytes) before setting the key decodes the base64 string. That's really wired.

I have created the repository to demostrate this behavior: https://github.com/Mikhail2048/jjwt-base64-bug-reporduction
There are 2 test cases, you can clone and run them. Jjwt version is 0.9.1 - latest I have found publically.

@Mikhail2048 you're not running the latest JJWT version, and those methods have been deprecated because people are confused about strings-as-passwords vs strings-as-base64url-encoded-keys.

JJWT's latest release is 0.11.5. The documentation is here: https://github.com/jwtk/jjwt/tree/0.11.5

You didn't see version upgrades (e.g. in maven central) because the JJWT artifact IDs changed starting with 0.10.0. Developers shouldn't rely on might show up in maven central, because Maven Central isn't a canonical source. Always check the project documentation (any project, not just JJWT) to find the latest version 😉

When I pass just bytes in the UTF-8 unicode encoding to method setSigningKey(byte[] key), then the library complains about signature.

This is not how Base64 encoding strings work, and they should never be used in this way. That is, calling base64EncodedString.getBytes(StandardCharsets.UTF_8) is always wrong. The bytes returned from this call are not the key bytes. They are the UTF-8 bytes of the string itself. They are different things.

If it helps, we've covered Base64 in security contexts in our documentation: https://github.com/jwtk/jjwt/tree/0.11.5#base64-security

Just a note: closing this as it doesn't represent actionable work for the JJWT codebase. For further questions, please ask them as documented here: https://github.com/jwtk/jjwt/tree/0.11.5#help-questions. Thanks!

@lhazlewood Thank you) Sorry, I really did not know there were a newer version of this library