> It's important to note that my experiment is not JWT.
> When you reduce JWT to a thing that is secure,
> you give up the "algorithm agility" that is a proud part
> of the specification.
I don't agree with him though, unless the standard requires to implement all of the available algorithms, one may choose to implement only those that he/she deems safe/worth.
Agreed. I view this flexibility as a developer feature, not a client feature.
> Finally, note that it is an application decision which algorithms may
> be used in a given context. Even if a JWT can be successfully
> validated, unless the algorithms used in the JWT are acceptable to
> the application, it SHOULD reject the JWT.
From what I understand from the above, the server side can decide to _always_ reject the "none" algorithm and still qualify as a valid implementation. The fact that the "none" algorithm is implemented or not by the library becomes a detail.
I'm using JWT for an API, and the server is choosing which algorithm to chose.
Really don't understand why a client should bypass server.
So I still think the header is superfluous even for this use case.
edit: in fact, the client needs to know that it's base64 encoded to even read the header in the first place.
For example, both of these decoded headers are equivalent:
{ "alg": "HS256", "typ": "JWT" }
{ "typ": "JWT", "alg": "HS256" }
Obviously, these encode to two different values. If you reattach the wrong one, signature verification will fail.
Disclaimer: I maintain a Python JOSE library and have had to answer questions related to this on more than one occasion.
This is pretty standard for rolling signing keys and api auth methods and all kinds of stuff like that.
Which still support webbrowsers that were released before 2007. (But somehow, they can’t support Firefox Mobile. mmhhmk. Totally not a plot to get rid of mobile ad blocking.)
How do you tell RS256 and ES256 JWTs apart - so you can figure out how to validate them - unless the JWT actually encodes that information?
The trick is that JWT APIs need to force developers to choose which algorithms they want - having a `decode_jwt` function is not a good idea, `decode_es256_jwt` is much better. It'd validate that the alg in the header is correct, and return a specific error if it's not - if that error is returned, the developer can try `decode_rs256_jwt`.
This is how I've designed the API used in my OpenID Connect implementation. It works wonderfully.