jose4j は JDK 自身のプロバイダーの上に JWS、JWE、JWK、JWT を実装しています。署名には JsonWebSignature を、検証とクレームのチェックには JwtConsumerBuilder で構築した JwtConsumer を使います。0.9.7 は 256/384/512 の HS、RS、PS、ES と EdDSA で署名と検証ができました。ES256K、Ed25519、Ed448 はアルゴリズム名として認識されません。
デフォルトでは古典的な 2 つの攻撃をブロックしますが、アルゴリズムは制限しません。署名を明示的に無効にしない限り none は拒否され('none' is a blocked algorithm.)、鍵の種類も一致している必要があります。EC 鍵に対する RS256 トークンと、EC 鍵の PEM テキストを鍵とした HS256 トークンは、どちらも失敗しました(cannot be used for HMAC verification)。ただし、鍵で実行できる他のアルゴリズムはすべて受け入れられるため、サンプルのように setJwsAlgorithmConstraints(ConstraintType.PERMIT, ...) でアルゴリズムを固定してください。PEM のバイト列から作成した HmacKey は、偽造した HS256 トークンの検証を通しました。鍵は必ず設定から取得し、トークンが示す内容から決めてはいけません。
鍵長は厳格にチェックされます。ES256 は P-384 の鍵を拒否し(expects a key using P-256 but was P-384)、RFC 7518 がハッシュの出力以上の長さの鍵を求めているため、HS256 は 16 バイトの鍵を拒否しました。ES256 の署名は 64 バイトの生の r‖s で、DER の署名は Invalid JWS Signature で失敗します。長さは JWT デバッガーで確認できます。
クレームのデフォルトは、厳しい方向と緩い方向に分かれています。時刻のずれをまったく許容しない点は多くのチームの想定より厳格で、exp を必須としない点は想定より緩やかです。別のサービスからのトークンを読み取るすべてのコンシューマーで、setRequireExpirationTime()、setExpectedIssuer()、setExpectedAudience()、setAllowedClockSkewInSeconds() を設定すべきです。
暗号化されたトークンについては、jose4j が生成した JWE の内容を JWE インスペクターで確認できます。