New Upstream Release - libjose4j-java

Ready changes

Summary

Merged new upstream version: 0.7.12 (was: 0.7.7).

Resulting package

Built on 2022-05-16T10:54 (took 4m51s)

The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:

apt install -t fresh-releases libjose4j-java

Lintian Result

Diff

diff --git a/debian/changelog b/debian/changelog
index c102d54..22a110a 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+libjose4j-java (0.7.12-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Mon, 16 May 2022 10:50:35 -0000
+
 libjose4j-java (0.7.7-2) unstable; urgency=medium
 
   * Set upstream metadata fields: Repository, Repository-Browse.
diff --git a/pom.xml b/pom.xml
index 6771c62..f6085a5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,7 +19,7 @@
   
   <groupId>org.bitbucket.b_c</groupId>
   <artifactId>jose4j</artifactId>
-  <version>0.7.7</version>
+  <version>0.7.12</version>
   <packaging>jar</packaging>
   <name>jose4j</name>
   <description>
@@ -58,35 +58,29 @@
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
-      <version>4.13.1</version>
+      <version>4.13.2</version>
       <scope>test</scope>
     </dependency>
 
     <dependency>
       <groupId>ch.qos.logback</groupId>
       <artifactId>logback-classic</artifactId>
-      <version>1.0.7</version>
+      <version>1.2.11</version>
       <scope>test</scope>
     </dependency>
 
     <dependency>
       <groupId>org.bouncycastle</groupId>
       <artifactId>bcprov-jdk15on</artifactId>
-      <version>1.58</version>
+      <version>1.70</version>
       <scope>test</scope>
     </dependency>
 
     <dependency>
       <groupId>org.mockito</groupId>
       <artifactId>mockito-core</artifactId>
-      <version>2.0.3-beta</version>
+      <version>2.28.2</version>
       <scope>test</scope>
-      <exclusions>
-        <exclusion>  <!-- sigh, mvn idea:idea was pulling this transitive dependency into its class path rather than the newer one from via junit -->
-          <groupId>org.hamcrest</groupId>
-          <artifactId>hamcrest-core</artifactId>
-        </exclusion>
-      </exclusions>
     </dependency>
 
   </dependencies>
@@ -264,6 +258,6 @@
     <connection>scm:git:https://bitbucket.org/b_c/jose4j.git</connection>
     <developerConnection>scm:git:ssh://git@bitbucket.org/b_c/jose4j.git</developerConnection>
     <url>https://bitbucket.org/b_c/jose4j</url>
-    <tag>jose4j-0.7.7</tag>
+    <tag>jose4j-0.7.12</tag>
   </scm>
 </project>                                                     
diff --git a/src/main/java/org/jose4j/base64url/internal/apache/commons/codec/binary/Base64.java b/src/main/java/org/jose4j/base64url/internal/apache/commons/codec/binary/Base64.java
index 93e15ed..1afebce 100644
--- a/src/main/java/org/jose4j/base64url/internal/apache/commons/codec/binary/Base64.java
+++ b/src/main/java/org/jose4j/base64url/internal/apache/commons/codec/binary/Base64.java
@@ -41,13 +41,13 @@ import java.math.BigInteger;
  * </p>
  * <p>
  * The class can be parameterized in the following manner with various constructors:
+ * </p>
  * <ul>
  * <li>URL-safe mode: Default off.</li>
  * <li>Line length: Default 76. Line length that aren't multiples of 4 will still essentially end up being multiples of
- * 4 in the encoded data.
+ * 4 in the encoded data.</li>
  * <li>Line separator: Default is CRLF ("\r\n")</li>
  * </ul>
- * </p>
  * <p>
  * Since this class operates directly on byte streams, and not character streams, it is hard-coded to only
  * encode/decode character encodings which are compatible with the lower 127 ASCII chart (ISO-8859-1, Windows-1252,
@@ -217,7 +217,7 @@ public class Base64 extends BaseNCodec {
      *
      * @param lineLength
      *            Each line of encoded data will be at most of the given length (rounded down to nearest multiple of
-     *            4). If lineLength <= 0, then the output will not be divided into lines (chunks). Ignored when
+     *            4). If lineLength &lt;= 0, then the output will not be divided into lines (chunks). Ignored when
      *            decoding.
      * @since 1.4
      */
@@ -240,7 +240,7 @@ public class Base64 extends BaseNCodec {
      *
      * @param lineLength
      *            Each line of encoded data will be at most of the given length (rounded down to nearest multiple of
-     *            4). If lineLength <= 0, then the output will not be divided into lines (chunks). Ignored when
+     *            4). If lineLength &lt;= 0, then the output will not be divided into lines (chunks). Ignored when
      *            decoding.
      * @param lineSeparator
      *            Each line of encoded data will end with this sequence of bytes.
@@ -267,7 +267,7 @@ public class Base64 extends BaseNCodec {
      *
      * @param lineLength
      *            Each line of encoded data will be at most of the given length (rounded down to nearest multiple of
-     *            4). If lineLength <= 0, then the output will not be divided into lines (chunks). Ignored when
+     *            4). If lineLength &lt;= 0, then the output will not be divided into lines (chunks). Ignored when
      *            decoding.
      * @param lineSeparator
      *            Each line of encoded data will end with this sequence of bytes.
diff --git a/src/main/java/org/jose4j/base64url/internal/apache/commons/codec/binary/BaseNCodec.java b/src/main/java/org/jose4j/base64url/internal/apache/commons/codec/binary/BaseNCodec.java
index 17dc7c6..f05801b 100644
--- a/src/main/java/org/jose4j/base64url/internal/apache/commons/codec/binary/BaseNCodec.java
+++ b/src/main/java/org/jose4j/base64url/internal/apache/commons/codec/binary/BaseNCodec.java
@@ -250,6 +250,7 @@ public abstract class BaseNCodec {
      *
      * @param size minimum spare space required
      * @param context the context to be used
+     * @return bytes
      */
     protected byte[] ensureBufferSize(final int size, final Context context){
         if ((context.buffer == null) || (context.buffer.length < context.pos + size)){
@@ -455,7 +456,7 @@ public abstract class BaseNCodec {
      * @param pArray byte[] array which will later be encoded
      *
      * @return amount of space needed to encoded the supplied array.
-     * Returns a long since a max-len array will require > Integer.MAX_VALUE
+     * Returns a long since a max-len array will require larger than Integer.MAX_VALUE
      */
     public long getEncodedLength(final byte[] pArray) {
         // Calculate non-chunked size - rounded up to allow for padding
diff --git a/src/main/java/org/jose4j/http/Get.java b/src/main/java/org/jose4j/http/Get.java
index 1d66b15..7167af9 100644
--- a/src/main/java/org/jose4j/http/Get.java
+++ b/src/main/java/org/jose4j/http/Get.java
@@ -73,6 +73,7 @@ public class Get implements SimpleGet
                 URLConnection urlConnection = (proxy == null) ? url.openConnection() : url.openConnection(proxy);
                 urlConnection.setConnectTimeout(connectTimeout);
                 urlConnection.setReadTimeout(readTimeout);
+                preventHttpCaching(urlConnection);
 
                 setUpTls(urlConnection);
 
@@ -112,6 +113,11 @@ public class Get implements SimpleGet
         }
     }
 
+    private void preventHttpCaching(URLConnection urlConnection) {
+        urlConnection.setUseCaches(false);
+        urlConnection.setRequestProperty("Cache-Control", "no-cache");
+    }
+
     private String getBody(URLConnection urlConnection, String charset) throws IOException
     {
         StringWriter writer = new StringWriter();
diff --git a/src/main/java/org/jose4j/jca/ProviderContext.java b/src/main/java/org/jose4j/jca/ProviderContext.java
index ce8e6b5..ace21cf 100644
--- a/src/main/java/org/jose4j/jca/ProviderContext.java
+++ b/src/main/java/org/jose4j/jca/ProviderContext.java
@@ -114,6 +114,7 @@ public class ProviderContext
         /**
          *  Gets the general JCA provider to be used for all relevant operations when
          *  a more specific one isn't set.
+         * @return the general JCA provider name
          */
         public String getGeneralProvider()
         {
diff --git a/src/main/java/org/jose4j/json/JsonHeaderUtil.java b/src/main/java/org/jose4j/json/JsonHeaderUtil.java
index ff47f66..c01bc58 100644
--- a/src/main/java/org/jose4j/json/JsonHeaderUtil.java
+++ b/src/main/java/org/jose4j/json/JsonHeaderUtil.java
@@ -27,6 +27,9 @@ public class JsonHeaderUtil
 {
     /**
      * @deprecated please use JsonUtil
+     * @param jsonString Sting
+     * @return Map
+     * @throws JoseException JoseException
      */
     public static Map<String,Object> parseJson(String jsonString) throws JoseException
     {
@@ -35,6 +38,8 @@ public class JsonHeaderUtil
 
     /**
      * @deprecated please use JsonUtil
+     * @param map Map
+     * @return String
      */
     public static String toJson(Map<String,?> map)
     {
diff --git a/src/main/java/org/jose4j/json/internal/json_simple/ItemList.java b/src/main/java/org/jose4j/json/internal/json_simple/ItemList.java
index 85478ae..0fd0dac 100644
--- a/src/main/java/org/jose4j/json/internal/json_simple/ItemList.java
+++ b/src/main/java/org/jose4j/json/internal/json_simple/ItemList.java
@@ -9,10 +9,11 @@ import java.util.List;
 import java.util.StringTokenizer;
 
 /**
- * |a:b:c| => |a|,|b|,|c|
- * |:| => ||,||
- * |a:| => |a|,||
- * @author (originally) FangYidong<fangyidong@yahoo.com.cn>
+ *
+ * |a:b:c| =&gt; |a|,|b|,|c|
+ * |:| =&gt; ||,||
+ * |a:| =&gt; |a|,||
+ * @author (originally) FangYidong fangyidong@yahoo.com.cn
  */
 public class ItemList {
 	private String sp=",";
diff --git a/src/main/java/org/jose4j/json/internal/json_simple/JSONArray.java b/src/main/java/org/jose4j/json/internal/json_simple/JSONArray.java
index c3ff1b8..e102710 100644
--- a/src/main/java/org/jose4j/json/internal/json_simple/JSONArray.java
+++ b/src/main/java/org/jose4j/json/internal/json_simple/JSONArray.java
@@ -14,7 +14,7 @@ import java.util.Iterator;
 /**
  * A JSON array. JSONObject supports java.util.List interface.
  * 
- * @author (originally) FangYidong<fangyidong@yahoo.com.cn>
+ * @author (originally) FangYidong fangyidong@yahoo.com.cn
  */
 public class JSONArray extends ArrayList implements JSONAware, JSONStreamAware {
 	private static final long serialVersionUID = 3957988303675231981L;
@@ -42,8 +42,9 @@ public class JSONArray extends ArrayList implements JSONAware, JSONStreamAware {
      * 
      * @see org.jose4j.json.internal.json_simple.JSONValue#writeJSONString(Object, Writer)
      * 
-     * @param collection
-     * @param out
+     * @param collection Collection
+     * @param out Writer
+	 * @throws IOException IOException
      */
 	public static void writeJSONString(Collection collection, Writer out) throws IOException{
 		if(collection == null){
@@ -82,7 +83,7 @@ public class JSONArray extends ArrayList implements JSONAware, JSONStreamAware {
 	 * 
 	 * @see org.jose4j.json.internal.json_simple.JSONValue#toJSONString(Object)
 	 * 
-	 * @param collection
+	 * @param collection Collection
 	 * @return JSON text, or "null" if list is null.
 	 */
 	public static String toJSONString(Collection collection){
diff --git a/src/main/java/org/jose4j/json/internal/json_simple/JSONAware.java b/src/main/java/org/jose4j/json/internal/json_simple/JSONAware.java
index 5c3a715..3ca3fc8 100644
--- a/src/main/java/org/jose4j/json/internal/json_simple/JSONAware.java
+++ b/src/main/java/org/jose4j/json/internal/json_simple/JSONAware.java
@@ -2,7 +2,7 @@ package org.jose4j.json.internal.json_simple;
 
 /**
  * Beans that support customized output of JSON text shall implement this interface.  
- * @author (originally) FangYidong<fangyidong@yahoo.com.cn>
+ * @author (originally) FangYidong fangyidong@yahoo.com.cn
  */
 public interface JSONAware {
 	/**
diff --git a/src/main/java/org/jose4j/json/internal/json_simple/JSONObject.java b/src/main/java/org/jose4j/json/internal/json_simple/JSONObject.java
index 5f15359..cd235b0 100644
--- a/src/main/java/org/jose4j/json/internal/json_simple/JSONObject.java
+++ b/src/main/java/org/jose4j/json/internal/json_simple/JSONObject.java
@@ -14,7 +14,7 @@ import java.util.Map;
 /**
  * A JSON object. Key value pairs are unordered. JSONObject supports java.util.Map interface.
  * 
- * @author (originally) FangYidong<fangyidong@yahoo.com.cn>
+ * @author (originally) FangYidong fangyidong@yahoo.com.cn
  */
 public class JSONObject extends HashMap implements Map, JSONAware, JSONStreamAware{
 	
@@ -29,7 +29,7 @@ public class JSONObject extends HashMap implements Map, JSONAware, JSONStreamAwa
 	 * Allows creation of a JSONObject from a Map. After that, both the
 	 * generated JSONObject and the Map can be modified independently.
 	 * 
-	 * @param map
+	 * @param map Map
 	 */
 	public JSONObject(Map map) {
 		super(map);
@@ -42,8 +42,9 @@ public class JSONObject extends HashMap implements Map, JSONAware, JSONStreamAwa
      * 
      * @see org.jose4j.json.internal.json_simple.JSONValue#writeJSONString(Object, Writer)
      * 
-     * @param map
-     * @param out
+     * @param map Map
+     * @param out Writer
+	 * @throws IOException IOException
      */
 	public static void writeJSONString(Map map, Writer out) throws IOException {
 		if(map == null){
@@ -80,7 +81,7 @@ public class JSONObject extends HashMap implements Map, JSONAware, JSONStreamAwa
 	 * 
 	 * @see org.jose4j.json.internal.json_simple.JSONValue#toJSONString(Object)
 	 * 
-	 * @param map
+	 * @param map Map
 	 * @return JSON text, or "null" if map is null.
 	 */
 	public static String toJSONString(Map map){
@@ -123,7 +124,7 @@ public class JSONObject extends HashMap implements Map, JSONAware, JSONStreamAwa
 	 * 
 	 * @see org.jose4j.json.internal.json_simple.JSONValue#escape(String)
 	 * 
-	 * @param s
+	 * @param s String
 	 * @return string
 	 */
 	public static String escape(String s){
diff --git a/src/main/java/org/jose4j/json/internal/json_simple/JSONStreamAware.java b/src/main/java/org/jose4j/json/internal/json_simple/JSONStreamAware.java
index 52e11cb..2d4761c 100644
--- a/src/main/java/org/jose4j/json/internal/json_simple/JSONStreamAware.java
+++ b/src/main/java/org/jose4j/json/internal/json_simple/JSONStreamAware.java
@@ -5,11 +5,13 @@ import java.io.Writer;
 
 /**
  * Beans that support customized output of JSON text to a writer shall implement this interface.  
- * @author (originally) FangYidong<fangyidong@yahoo.com.cn>
+ * @author (originally) FangYidong fangyidong@yahoo.com.cn
  */
 public interface JSONStreamAware {
 	/**
 	 * write JSON string to out.
+	 * @param out Writer
+	 * @throws IOException IOException
 	 */
 	void writeJSONString(Writer out) throws IOException;
 }
diff --git a/src/main/java/org/jose4j/json/internal/json_simple/JSONValue.java b/src/main/java/org/jose4j/json/internal/json_simple/JSONValue.java
index 0c182af..dafc5db 100644
--- a/src/main/java/org/jose4j/json/internal/json_simple/JSONValue.java
+++ b/src/main/java/org/jose4j/json/internal/json_simple/JSONValue.java
@@ -18,7 +18,7 @@ import org.jose4j.json.internal.json_simple.parser.ParseException;
 
 
 /**
- * @author (originally) FangYidong<fangyidong@yahoo.com.cn>
+ * @author (originally) FangYidong fangyidong@yahoo.com.cn
  */
 public class JSONValue {
 	/**
@@ -28,7 +28,7 @@ public class JSONValue {
 	 * @see org.jose4j.json.internal.json_simple.parser.JSONParser#parse(Reader)
 	 * @see #parseWithException(Reader)
 	 * 
-	 * @param in
+	 * @param in Reader
 	 * @return Instance of the following:
 	 *	org.jose4j.json.org.json.json_simple.JSONObject,
 	 * 	org.jose4j.json.org.json.json_simple.JSONArray,
@@ -58,7 +58,7 @@ public class JSONValue {
 	 * @see org.jose4j.json.internal.json_simple.parser.JSONParser#parse(Reader)
 	 * @see #parseWithException(Reader)
 	 * 
-	 * @param s
+	 * @param s String
 	 * @return Instance of the following:
 	 *	org.jose4j.json.org.json.json_simple.JSONObject,
 	 * 	org.jose4j.json.org.json.json_simple.JSONArray,
@@ -81,7 +81,7 @@ public class JSONValue {
 	 * 
 	 * @see org.jose4j.json.internal.json_simple.parser.JSONParser
 	 * 
-	 * @param in
+	 * @param in Reader
 	 * @return Instance of the following:
 	 * 	org.jose4j.json.org.json.json_simple.JSONObject,
 	 * 	org.jose4j.json.org.json.json_simple.JSONArray,
@@ -90,8 +90,8 @@ public class JSONValue {
 	 * 	java.lang.Boolean,
 	 * 	null
 	 * 
-	 * @throws IOException
-	 * @throws ParseException
+	 * @throws IOException IOException
+	 * @throws ParseException ParseException
 	 */
 	public static Object parseWithException(Reader in) throws IOException, ParseException{
 		JSONParser parser=new JSONParser();
@@ -114,8 +114,9 @@ public class JSONValue {
      * @see org.jose4j.json.internal.json_simple.JSONObject#writeJSONString(Map, Writer)
      * @see org.jose4j.json.internal.json_simple.JSONArray#writeJSONString(Collection, Writer)
      * 
-     * @param value
-     * @param out
+     * @param value value
+     * @param out  Writer
+	 * @throws IOException IOException
      */
 	public static void writeJSONString(Object value, Writer out) throws IOException {
 		if(value == null){
@@ -235,7 +236,7 @@ public class JSONValue {
 	 * @see org.jose4j.json.internal.json_simple.JSONObject#toJSONString(Map)
 	 * @see org.jose4j.json.internal.json_simple.JSONArray#toJSONString(Collection)
 	 * 
-	 * @param value
+	 * @param value Object
 	 * @return JSON text, or "null" if value is null or it's an NaN or an INF number.
 	 */
 	public static String toJSONString(Object value){
@@ -252,7 +253,7 @@ public class JSONValue {
 
 	/**
 	 * Escape quotes, \, /, \r, \n, \b, \f, \t and other control characters (U+0000 through U+001F).
-	 * @param s
+	 * @param s String
 	 * @return string
 	 */
 	public static String escape(String s){
diff --git a/src/main/java/org/jose4j/json/internal/json_simple/parser/ContainerFactory.java b/src/main/java/org/jose4j/json/internal/json_simple/parser/ContainerFactory.java
index 52d5f2e..e5b1f26 100644
--- a/src/main/java/org/jose4j/json/internal/json_simple/parser/ContainerFactory.java
+++ b/src/main/java/org/jose4j/json/internal/json_simple/parser/ContainerFactory.java
@@ -8,7 +8,7 @@ import java.util.Map;
  * 
  * @see org.jose4j.json.internal.json_simple.parser.JSONParser#parse(java.io.Reader, ContainerFactory)
  * 
- * @author (originally) FangYidong<fangyidong@yahoo.com.cn>
+ * @author (originally) FangYidong fangyidong@yahoo.com.cn
  */
 public interface ContainerFactory {
 	/**
diff --git a/src/main/java/org/jose4j/json/internal/json_simple/parser/ContentHandler.java b/src/main/java/org/jose4j/json/internal/json_simple/parser/ContentHandler.java
index 020998f..f6907f5 100644
--- a/src/main/java/org/jose4j/json/internal/json_simple/parser/ContentHandler.java
+++ b/src/main/java/org/jose4j/json/internal/json_simple/parser/ContentHandler.java
@@ -8,7 +8,7 @@ import java.io.IOException;
  * @see org.xml.sax.ContentHandler
  * @see org.jose4j.json.internal.json_simple.parser.JSONParser#parse(java.io.Reader, ContentHandler, boolean)
  * 
- * @author (originally) FangYidong<fangyidong@yahoo.com.cn>
+ * @author (originally) FangYidong fangyidong@yahoo.com.cn
  */
 public interface ContentHandler {
 	/**
@@ -17,13 +17,15 @@ public interface ContentHandler {
      * 
 	 * @throws ParseException 
 	 * 			- JSONParser will stop and throw the same exception to the caller when receiving this exception.
+	 * @throws IOException IOException
 	 */
 	void startJSON() throws ParseException, IOException;
 	
 	/**
 	 * Receive notification of the end of JSON processing.
 	 * 
-	 * @throws ParseException
+	 * @throws ParseException ParseException
+	 * @throws IOException IOException
 	 */
 	void endJSON() throws ParseException, IOException;
 	
@@ -33,6 +35,7 @@ public interface ContentHandler {
 	 * @return false if the handler wants to stop parsing after return.
 	 * @throws ParseException
      *          - JSONParser will stop and throw the same exception to the caller when receiving this exception.
+	 * @throws IOException IOException
      * @see #endJSON
 	 */
 	boolean startObject() throws ParseException, IOException;
@@ -41,7 +44,8 @@ public interface ContentHandler {
 	 * Receive notification of the end of a JSON object.
 	 * 
 	 * @return false if the handler wants to stop parsing after return.
-	 * @throws ParseException
+	 * @throws ParseException ParseException
+	 * @throws IOException IOException
      * 
      * @see #startObject
 	 */
@@ -53,7 +57,8 @@ public interface ContentHandler {
 	 * @param key - Key of a JSON object entry. 
 	 * 
 	 * @return false if the handler wants to stop parsing after return.
-	 * @throws ParseException
+	 * @throws ParseException ParseException
+	 * @throws IOException IOException
      * 
      * @see #endObjectEntry
 	 */
@@ -63,7 +68,8 @@ public interface ContentHandler {
 	 * Receive notification of the end of the value of previous object entry.
 	 * 
 	 * @return false if the handler wants to stop parsing after return.
-	 * @throws ParseException
+	 * @throws ParseException ParseException
+	 * @throws IOException IOException
      * 
      * @see #startObjectEntry
 	 */
@@ -73,8 +79,8 @@ public interface ContentHandler {
 	 * Receive notification of the beginning of a JSON array.
 	 * 
 	 * @return false if the handler wants to stop parsing after return.
-	 * @throws ParseException
-     * 
+	 * @throws ParseException ParseException
+	 * @throws IOException IOException
      * @see #endArray
 	 */
 	boolean startArray() throws ParseException, IOException;
@@ -83,7 +89,8 @@ public interface ContentHandler {
 	 * Receive notification of the end of a JSON array.
 	 * 
 	 * @return false if the handler wants to stop parsing after return.
-	 * @throws ParseException
+	 * @throws ParseException ParseException
+	 * @throws IOException IOException
      * 
      * @see #startArray
 	 */
@@ -103,7 +110,8 @@ public interface ContentHandler {
 	 * 			null
 	 * 
 	 * @return false if the handler wants to stop parsing after return.
-	 * @throws ParseException
+	 * @throws ParseException ParseException
+	 * @throws IOException IOException
 	 */
 	boolean primitive(Object value) throws ParseException, IOException;
 		
diff --git a/src/main/java/org/jose4j/json/internal/json_simple/parser/JSONParser.java b/src/main/java/org/jose4j/json/internal/json_simple/parser/JSONParser.java
index 05d282a..bd09813 100644
--- a/src/main/java/org/jose4j/json/internal/json_simple/parser/JSONParser.java
+++ b/src/main/java/org/jose4j/json/internal/json_simple/parser/JSONParser.java
@@ -18,7 +18,7 @@ import org.jose4j.json.internal.json_simple.JSONObject;
 /**
  * Parser for JSON text. Please note that JSONParser is NOT thread-safe.
  * 
- * @author (originally) FangYidong<fangyidong@yahoo.com.cn>
+ * @author (originally) FangYidong fangyidong@yahoo.com.cn
  */
 public class JSONParser {
 	public static final int S_INIT=0;
@@ -56,8 +56,6 @@ public class JSONParser {
      * Reset the parser to the initial state with a new character reader.
      * 
      * @param in - The new character reader.
-     * @throws IOException
-     * @throws ParseException
      */
 	public void reset(Reader in){
 		lexer.yyreset(in);
@@ -95,8 +93,8 @@ public class JSONParser {
 	/**
 	 * Parse JSON text into java object from the input source.
 	 * 	
-	 * @param in
-     * @param containerFactory - Use this factory to createyour own JSON object and JSON array containers.
+	 * @param in Reader
+     * @param containerFactory - Use this factory to create your own JSON object and JSON array containers.
 	 * @return Instance of the following:
 	 *  org.jose4j.json.org.json.json_simple.JSONObject,
 	 * 	org.jose4j.json.org.json.json_simple.JSONArray,
@@ -105,8 +103,8 @@ public class JSONParser {
 	 * 	java.lang.Boolean,
 	 * 	null
 	 * 
-	 * @throws IOException
-	 * @throws ParseException
+	 * @throws IOException IOException
+	 * @throws ParseException ParseException
 	 */
 	public Object parse(Reader in, ContainerFactory containerFactory) throws IOException, ParseException{
 		reset(in);
@@ -317,14 +315,14 @@ public class JSONParser {
 	 * 
 	 * @see ContentHandler
 	 * 
-	 * @param in
-	 * @param contentHandler
+	 * @param in Reader
+	 * @param contentHandler ContentHandler
 	 * @param isResume - Indicates if it continues previous parsing operation.
      *                   If set to true, resume parsing the old stream, and parameter 'in' will be ignored. 
 	 *                   If this method is called for the first time in this instance, isResume will be ignored.
 	 * 
-	 * @throws IOException
-	 * @throws ParseException
+	 * @throws IOException IOException
+	 * @throws ParseException ParseException
 	 */
 	public void parse(Reader in, ContentHandler contentHandler, boolean isResume) throws IOException, ParseException{
 		if(!isResume){
diff --git a/src/main/java/org/jose4j/json/internal/json_simple/parser/ParseException.java b/src/main/java/org/jose4j/json/internal/json_simple/parser/ParseException.java
index ab4b6ff..b2e5c28 100644
--- a/src/main/java/org/jose4j/json/internal/json_simple/parser/ParseException.java
+++ b/src/main/java/org/jose4j/json/internal/json_simple/parser/ParseException.java
@@ -3,7 +3,7 @@ package org.jose4j.json.internal.json_simple.parser;
 /**
  * ParseException explains why and where the error occurs in source JSON text.
  * 
- * @author (originally) FangYidong<fangyidong@yahoo.com.cn>
+ * @author (originally) FangYidong fangyidong@yahoo.com.cn
  *
  */
 public class ParseException extends Exception {
diff --git a/src/main/java/org/jose4j/json/internal/json_simple/parser/Yytoken.java b/src/main/java/org/jose4j/json/internal/json_simple/parser/Yytoken.java
index f1b1a8e..302b48b 100644
--- a/src/main/java/org/jose4j/json/internal/json_simple/parser/Yytoken.java
+++ b/src/main/java/org/jose4j/json/internal/json_simple/parser/Yytoken.java
@@ -5,7 +5,7 @@
 package org.jose4j.json.internal.json_simple.parser;
 
 /**
- * @author (originally) FangYidong<fangyidong@yahoo.com.cn>
+ * @author (originally) FangYidong fangyidong@yahoo.com.cn
  */
 public class Yytoken {
 	public static final int TYPE_VALUE=0;//JSON primitive value: string,number,boolean,null
diff --git a/src/main/java/org/jose4j/jwe/AesKeyWrapManagementAlgorithm.java b/src/main/java/org/jose4j/jwe/AesKeyWrapManagementAlgorithm.java
index 711659d..1b45d25 100644
--- a/src/main/java/org/jose4j/jwe/AesKeyWrapManagementAlgorithm.java
+++ b/src/main/java/org/jose4j/jwe/AesKeyWrapManagementAlgorithm.java
@@ -20,9 +20,13 @@ import org.jose4j.jwa.AlgorithmAvailability;
 import org.jose4j.jwk.OctetSequenceJsonWebKey;
 import org.jose4j.jwx.KeyValidationSupport;
 import org.jose4j.keys.KeyPersuasion;
+import org.jose4j.lang.ExceptionHelp;
 import org.jose4j.lang.InvalidKeyException;
 
+import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
 import java.security.Key;
+import java.security.NoSuchAlgorithmException;
 
 /**
  */
@@ -32,7 +36,7 @@ public class AesKeyWrapManagementAlgorithm extends WrappingKeyManagementAlgorith
 
     public AesKeyWrapManagementAlgorithm(String alg, int keyByteLength)
     {
-        super("AESWrap", alg);
+        super("AESWrap", alg); // -> AES/KW/NoPadding as of Java 17 but using AESWrap for compatibility
         setKeyType(OctetSequenceJsonWebKey.KEY_TYPE);
         setKeyPersuasion(KeyPersuasion.SYMMETRIC);
         this.keyByteLength = keyByteLength;
@@ -64,8 +68,17 @@ public class AesKeyWrapManagementAlgorithm extends WrappingKeyManagementAlgorith
     public boolean isAvailable()
     {
         int aesByteKeyLength = getKeyByteLength();
-        String agl = getJavaAlgorithm();
-        return AlgorithmAvailability.isAvailable("Cipher", agl) && CipherStrengthSupport.isAvailable(agl, aesByteKeyLength);
+        String alg = getJavaAlgorithm();
+        try
+        {
+            Cipher.getInstance(alg);
+            return CipherStrengthSupport.isAvailable(alg, aesByteKeyLength);
+        }
+        catch (NoSuchAlgorithmException | NoSuchPaddingException e)
+        {
+            log.debug("{} for {} is not available ({}).", alg, getAlgorithmIdentifier(), ExceptionHelp.toStringWithCauses(e));
+            return false;
+        }
     }
 
     AesKeyWrapManagementAlgorithm setUseGeneralProviderContext()
diff --git a/src/main/java/org/jose4j/jwk/DecryptionJwkSelector.java b/src/main/java/org/jose4j/jwk/DecryptionJwkSelector.java
index 99b04f3..597e90c 100644
--- a/src/main/java/org/jose4j/jwk/DecryptionJwkSelector.java
+++ b/src/main/java/org/jose4j/jwk/DecryptionJwkSelector.java
@@ -17,8 +17,12 @@
 package org.jose4j.jwk;
 
 import org.jose4j.jwe.JsonWebEncryption;
+import org.jose4j.lang.ExceptionHelp;
 import org.jose4j.lang.JoseException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
+import java.security.Key;
 import java.util.Collection;
 import java.util.List;
 
@@ -27,6 +31,8 @@ import java.util.List;
  */
 public class DecryptionJwkSelector
 {
+    private static final Logger log = LoggerFactory.getLogger(DecryptionJwkSelector.class);
+
     public JsonWebKey select(JsonWebEncryption jwe, Collection<JsonWebKey> keys) throws JoseException
     {
         List<JsonWebKey> jsonWebKeys = selectList(jwe, keys);
@@ -38,4 +44,39 @@ public class DecryptionJwkSelector
         SimpleJwkFilter filter = SelectorSupport.filterForInboundEncrypted(jwe);
         return filter.filter(keys);
     }
+
+    public JsonWebKey attemptDecryptDisambiguate(JsonWebEncryption jwe, List<JsonWebKey> jsonWebKeys)
+    {
+        for (JsonWebKey jwk : jsonWebKeys)
+        {
+            Key key;
+            if (jwk instanceof PublicJsonWebKey)
+            {
+                PublicJsonWebKey publicJwk = (PublicJsonWebKey) jwk;
+                key = publicJwk.getPrivateKey();
+            }
+            else
+            {
+                key = jwk.getKey();
+            }
+
+            if (key != null)
+            {
+                jwe.setKey(key);
+                try {
+                    byte[] plaintextBytes = jwe.getPlaintextBytes();
+                    if (plaintextBytes != null)
+                    {
+                        return jwk;
+                    }
+                }
+                catch (JoseException e)
+                {
+                    log.debug("Not using key (kid={}) b/c attempt to decrypt failed trying to disambiguate ({}).", jwk.getKeyId(), ExceptionHelp.toStringWithCauses(e));
+                }
+            }
+        }
+
+        return null;
+    }
 }
diff --git a/src/main/java/org/jose4j/jwk/HttpsJwks.java b/src/main/java/org/jose4j/jwk/HttpsJwks.java
index 1a07fc5..e3f078d 100644
--- a/src/main/java/org/jose4j/jwk/HttpsJwks.java
+++ b/src/main/java/org/jose4j/jwk/HttpsJwks.java
@@ -131,7 +131,7 @@ public class HttpsJwks
     /**
      * Gets the JSON Web Keys from the JWKS endpoint location or from local cache, if appropriate.
      * @return a list of JsonWebKeys
-     * @throws JoseException if an problem is encountered parsing the JSON content into JSON Web Keys.
+     * @throws JoseException if a problem is encountered parsing the JSON content into JSON Web Keys.
      * @throws IOException if a problem is encountered making the HTTP request.
      */
     public List<JsonWebKey> getJsonWebKeys() throws JoseException, IOException
diff --git a/src/main/java/org/jose4j/jwk/JsonWebKey.java b/src/main/java/org/jose4j/jwk/JsonWebKey.java
index 1e95068..f04a086 100644
--- a/src/main/java/org/jose4j/jwk/JsonWebKey.java
+++ b/src/main/java/org/jose4j/jwk/JsonWebKey.java
@@ -78,6 +78,7 @@ public abstract class JsonWebKey implements Serializable
 
     /**
      * @deprecated deprecated in favor {@link #getKey()} or {@link PublicJsonWebKey#getPublicKey()}
+     * @return PublicKey
      */
     public PublicKey getPublicKey()
     {
diff --git a/src/main/java/org/jose4j/jwk/PublicJsonWebKey.java b/src/main/java/org/jose4j/jwk/PublicJsonWebKey.java
index 983a5bb..0c081d2 100644
--- a/src/main/java/org/jose4j/jwk/PublicJsonWebKey.java
+++ b/src/main/java/org/jose4j/jwk/PublicJsonWebKey.java
@@ -130,6 +130,7 @@ public abstract class PublicJsonWebKey extends JsonWebKey
 
     /**
      * @deprecated as of 0.3.2 use {@link #toJson(org.jose4j.jwk.JsonWebKey.OutputControlLevel)}
+     * @param writeOutPrivateKeyToJson don't use this
      */
     public void setWriteOutPrivateKeyToJson(boolean writeOutPrivateKeyToJson)
     {
diff --git a/src/main/java/org/jose4j/jwk/RsaJsonWebKey.java b/src/main/java/org/jose4j/jwk/RsaJsonWebKey.java
index a8babe0..01ce884 100644
--- a/src/main/java/org/jose4j/jwk/RsaJsonWebKey.java
+++ b/src/main/java/org/jose4j/jwk/RsaJsonWebKey.java
@@ -112,6 +112,7 @@ public class RsaJsonWebKey extends PublicJsonWebKey
 
     /**
      * @deprecated deprecated in favor of the more consistently named {@link #getRsaPublicKey()}
+     * @return RSAPublicKey
      */
     public RSAPublicKey getRSAPublicKey()
     {
diff --git a/src/main/java/org/jose4j/jws/EcdsaUsingShaAlgorithm.java b/src/main/java/org/jose4j/jws/EcdsaUsingShaAlgorithm.java
index 0450b97..5e27409 100644
--- a/src/main/java/org/jose4j/jws/EcdsaUsingShaAlgorithm.java
+++ b/src/main/java/org/jose4j/jws/EcdsaUsingShaAlgorithm.java
@@ -20,11 +20,14 @@ package org.jose4j.jws;
 import org.jose4j.jca.ProviderContext;
 import org.jose4j.jwa.CryptoPrimitive;
 import org.jose4j.jwk.EllipticCurveJsonWebKey;
+import org.jose4j.keys.BigEndianBigInteger;
 import org.jose4j.keys.EllipticCurves;
+import org.jose4j.lang.ByteUtil;
 import org.jose4j.lang.InvalidKeyException;
 import org.jose4j.lang.JoseException;
 
 import java.io.IOException;
+import java.math.BigInteger;
 import java.security.Key;
 import java.security.PrivateKey;
 import java.security.PublicKey;
@@ -37,8 +40,8 @@ import java.security.spec.EllipticCurve;
  */
 public class EcdsaUsingShaAlgorithm extends BaseSignatureAlgorithm implements JsonWebSignatureAlgorithm
 {
-    private String curveName;
-    private int signatureByteLength;
+    private final String curveName;
+    private final int signatureByteLength;
 
     public EcdsaUsingShaAlgorithm(String id, String javaAlgo, String curveName, int signatureByteLength)
     {
@@ -49,6 +52,25 @@ public class EcdsaUsingShaAlgorithm extends BaseSignatureAlgorithm implements Js
 
     public boolean verifySignature(byte[] signatureBytes, Key key, byte[] securedInputBytes, ProviderContext providerContext) throws JoseException
     {
+        // some pre-validation before calling the JCA to verify the signature
+        // inspired by CVE-2022-21449 https://neilmadden.blog/2022/04/19/psychic-signatures-in-java/
+        if (signatureBytes.length > signatureByteLength)
+        {
+            return false;
+        }
+
+        final byte[] rb = ByteUtil.leftHalf(signatureBytes);
+        final BigInteger r = BigEndianBigInteger.fromBytes(rb);
+        final byte[] sb = ByteUtil.rightHalf(signatureBytes);
+        final BigInteger s = BigEndianBigInteger.fromBytes(sb);
+        ECParameterSpec ecParams = EllipticCurves.getSpec(curveName);
+        final BigInteger orderN = ecParams.getOrder();
+
+        if (r.mod(orderN).equals(BigInteger.ZERO) || s.mod(orderN).equals(BigInteger.ZERO))
+        {
+            return false;
+        }
+
         byte[] derEncodedSignatureBytes;
         try
         {
@@ -96,7 +118,7 @@ public class EcdsaUsingShaAlgorithm extends BaseSignatureAlgorithm implements Js
 
         int i;
 
-        for (i = rawLen; (i > 0) && (concatenatedSignatureBytes[rawLen - i] == 0); i--);
+        for (i = rawLen; (i > 1) && (concatenatedSignatureBytes[rawLen - i] == 0); i--);
 
         int j = i;
 
@@ -107,7 +129,7 @@ public class EcdsaUsingShaAlgorithm extends BaseSignatureAlgorithm implements Js
 
         int k;
 
-        for (k = rawLen; (k > 0) && (concatenatedSignatureBytes[2*rawLen - k] == 0); k--);
+        for (k = rawLen; (k > 1) && (concatenatedSignatureBytes[2*rawLen - k] == 0); k--);
 
         int l = k;
 
diff --git a/src/main/java/org/jose4j/jws/HmacUsingShaAlgorithm.java b/src/main/java/org/jose4j/jws/HmacUsingShaAlgorithm.java
index 1950e70..d5c5e71 100644
--- a/src/main/java/org/jose4j/jws/HmacUsingShaAlgorithm.java
+++ b/src/main/java/org/jose4j/jws/HmacUsingShaAlgorithm.java
@@ -30,6 +30,7 @@ import org.jose4j.mac.MacUtil;
 import javax.crypto.Mac;
 import javax.crypto.SecretKey;
 import java.security.Key;
+import java.security.NoSuchAlgorithmException;
 
 /**
  */
@@ -110,7 +111,15 @@ public class HmacUsingShaAlgorithm extends AlgorithmInfo implements JsonWebSigna
     @Override
     public boolean isAvailable()
     {
-        return AlgorithmAvailability.isAvailable("Mac", getJavaAlgorithm());
+        try
+        {
+            Mac.getInstance(getJavaAlgorithm());
+        }
+        catch (NoSuchAlgorithmException e)
+        {
+            return false;
+        }
+        return true;
     }
 
     public static class HmacSha256 extends HmacUsingShaAlgorithm
diff --git a/src/main/java/org/jose4j/jws/JsonWebSignature.java b/src/main/java/org/jose4j/jws/JsonWebSignature.java
index 42c96cd..a5e129d 100644
--- a/src/main/java/org/jose4j/jws/JsonWebSignature.java
+++ b/src/main/java/org/jose4j/jws/JsonWebSignature.java
@@ -67,6 +67,7 @@ public class JsonWebSignature extends JsonWebStructure
     public void setPayload(String payload)
     {
         this.payloadBytes = StringUtil.getBytesUnchecked(payload, payloadCharEncoding);
+        this.encodedPayload = null;
     }
 
     /**
@@ -137,7 +138,7 @@ public class JsonWebSignature extends JsonWebStructure
      * BASE64URL(JWS Signature)
      * </p>
      * @return the Compact Serialization: the encoded header + "." + the encoded payload + "." + the encoded signature
-     * @throws JoseException
+     * @throws JoseException if an error condition is encountered during the process
      */
     public String getCompactSerialization() throws JoseException
     {
@@ -350,6 +351,7 @@ public class JsonWebSignature extends JsonWebStructure
      * verified when calling this method.
      * Use {@link #setPayloadCharEncoding(String)} before calling this method, to use a character
      * encoding other than UTF-8.
+     * @return the JWS payload
      */
     public String getUnverifiedPayload()
     {
diff --git a/src/main/java/org/jose4j/jwt/NumericDate.java b/src/main/java/org/jose4j/jwt/NumericDate.java
index 7347e49..db3e6c7 100644
--- a/src/main/java/org/jose4j/jwt/NumericDate.java
+++ b/src/main/java/org/jose4j/jwt/NumericDate.java
@@ -93,7 +93,7 @@ public class NumericDate
     {
         long secs = getValue();
         long millis = secs * CONVERSION;
-        return  (! ((secs > 0 && millis < secs) || (secs < 0 && millis > secs) || (secs == 0 & millis != 0)));
+        return  (! ((secs > 0 && millis < secs) || (secs < 0 && millis > secs) || (secs == 0 && millis != 0)));
     }
 
     public boolean isBefore(NumericDate when)
diff --git a/src/main/java/org/jose4j/jwt/consumer/InvalidJwtException.java b/src/main/java/org/jose4j/jwt/consumer/InvalidJwtException.java
index e23c5a3..331fed9 100644
--- a/src/main/java/org/jose4j/jwt/consumer/InvalidJwtException.java
+++ b/src/main/java/org/jose4j/jwt/consumer/InvalidJwtException.java
@@ -88,13 +88,13 @@ public class InvalidJwtException extends Exception
     }
 
     /**
-     * Returns a <code>JwtContext</code> object including the <code>JwtClaims<code/>
+     * Returns a <code>JwtContext</code> object including the <code>JwtClaims</code>
      * representing the JWT processed
      * up to the point of this <code>InvalidJwtException</code> being thrown.
      * Some care should be taken when using this because, depending on what kind
      * of error was encountered in processing the JWT and
      * when it was encountered, the <code>JwtContext</code> may not be complete.
-     * @return the the <code>JwtContext</code>
+     * @return the <code>JwtContext</code>
      */
     public JwtContext getJwtContext()
     {
@@ -113,4 +113,12 @@ public class InvalidJwtException extends Exception
         }
         return sb.toString();
     }
+
+    /**
+     * Returns the original message of this exception without the details.
+     * @return the original message
+     */
+    public String getOriginalMessage() {
+        return super.getMessage();
+    }
 }
diff --git a/src/main/java/org/jose4j/jwt/consumer/JwtConsumer.java b/src/main/java/org/jose4j/jwt/consumer/JwtConsumer.java
index db467b3..ca1e707 100644
--- a/src/main/java/org/jose4j/jwt/consumer/JwtConsumer.java
+++ b/src/main/java/org/jose4j/jwt/consumer/JwtConsumer.java
@@ -236,13 +236,6 @@ public class JwtConsumer
                 {
                     JsonWebEncryption jwe = (JsonWebEncryption) currentJoseObject;
 
-                    Key key = decryptionKeyResolver.resolveKey(jwe, nestingContext);
-                    if (key != null && !key.equals(jwe.getKey()))
-                    {
-                        List<ErrorCodeValidator.Error> errors = Collections.singletonList(new ErrorCodeValidator.Error(MISCELLANEOUS, "Key resolution problem."));
-                        throw new InvalidJwtException("The resolved decryption key is different than the one originally used to decrypt the JWE.", errors, jwtContext);
-                    }
-
                     if (jweAlgorithmConstraints != null)
                     {
                         jweAlgorithmConstraints.checkConstraint(jwe.getAlgorithmHeaderValue());
diff --git a/src/main/java/org/jose4j/jwt/consumer/JwtConsumerBuilder.java b/src/main/java/org/jose4j/jwt/consumer/JwtConsumerBuilder.java
index 4e7edf1..92cd537 100644
--- a/src/main/java/org/jose4j/jwt/consumer/JwtConsumerBuilder.java
+++ b/src/main/java/org/jose4j/jwt/consumer/JwtConsumerBuilder.java
@@ -344,7 +344,7 @@ public class JwtConsumerBuilder
      * Set the DecryptionKeyResolver to use to select the key for JWE decryption.
      * A DecryptionKeyResolver enables a decryption key to be chosen dynamically based on more
      * information, like the JWE headers, about the message being processed.
-     * @param decryptionKeyResolver the VerificationKeyResolver
+     * @param decryptionKeyResolver the DecryptionKeyResolver
      * @return the same JwtConsumerBuilder
      * @see org.jose4j.keys.resolvers.JwksDecryptionKeyResolver
      */
@@ -385,6 +385,7 @@ public class JwtConsumerBuilder
     }
 
     /**
+     * <p>
      * Set the audience value(s) to use when validating the audience ("aud") claim of a JWT.
      * Audience validation will succeed, if any one of the provided values is equal to any one
      * of the values of the "aud" claim in the JWT.
diff --git a/src/main/java/org/jose4j/jwx/Headers.java b/src/main/java/org/jose4j/jwx/Headers.java
index 9340f45..6bd8bf8 100644
--- a/src/main/java/org/jose4j/jwx/Headers.java
+++ b/src/main/java/org/jose4j/jwx/Headers.java
@@ -88,18 +88,29 @@ public class Headers
         return headerMap.get(name);
     }
 
+    /**
+     *  @deprecated  Use {@link #getPublicJwkHeaderValue} instead.
+     */
+    @Deprecated
     public JsonWebKey getJwkHeaderValue(String name) throws JoseException
     {
-        Object objectHeaderValue = getObjectHeaderValue(name);
-        Map<String, Object> jwkParams = (Map<String, Object>) objectHeaderValue;
-        return jwkParams != null ? JsonWebKey.Factory.newJwk(jwkParams) : null;
+        return getPublicJwkHeaderValue(name,null);
     }
 
     public PublicJsonWebKey getPublicJwkHeaderValue(String name, String jcaProvider) throws JoseException
     {
         Object objectHeaderValue = getObjectHeaderValue(name);
         Map<String, Object> jwkParams = (Map<String, Object>) objectHeaderValue;
-        return jwkParams != null ? PublicJsonWebKey.Factory.newPublicJwk(jwkParams, jcaProvider) : null;
+        if (jwkParams != null)
+        {
+            PublicJsonWebKey publicJsonWebKey = PublicJsonWebKey.Factory.newPublicJwk(jwkParams, jcaProvider);
+            if (publicJsonWebKey.getPrivateKey() != null)
+            {
+                throw new JoseException(name + " header contains a private key, which it most definitely should not.");
+            }
+            return publicJsonWebKey;
+        }
+        return null;
     }
 
 
diff --git a/src/main/java/org/jose4j/jwx/JsonWebStructure.java b/src/main/java/org/jose4j/jwx/JsonWebStructure.java
index 5e2e631..3d80e39 100644
--- a/src/main/java/org/jose4j/jwx/JsonWebStructure.java
+++ b/src/main/java/org/jose4j/jwx/JsonWebStructure.java
@@ -107,6 +107,7 @@ public abstract class JsonWebStructure
 
     /**
      * @deprecated replaced by {@link #getHeaders()} and {@link org.jose4j.jwx.Headers#getFullHeaderAsJsonString()}
+     * @return the header as JSON
      */
     public String getHeader()
     {
diff --git a/src/main/java/org/jose4j/keys/resolvers/EmbeddedJwkVerificationKeyResolver.java b/src/main/java/org/jose4j/keys/resolvers/EmbeddedJwkVerificationKeyResolver.java
index ae1a167..f1ff0f8 100644
--- a/src/main/java/org/jose4j/keys/resolvers/EmbeddedJwkVerificationKeyResolver.java
+++ b/src/main/java/org/jose4j/keys/resolvers/EmbeddedJwkVerificationKeyResolver.java
@@ -29,7 +29,7 @@ public class EmbeddedJwkVerificationKeyResolver implements VerificationKeyResolv
         }
         catch (JoseException e)
         {
-            throw new UnresolvableKeyException("Problem processing jwk from JWS header", e);
+            throw new UnresolvableKeyException("Problem processing jwk from JWS header ("+e.getMessage()+")", e);
         }
 
         if (jwk == null)
diff --git a/src/main/java/org/jose4j/keys/resolvers/JwksDecryptionKeyResolver.java b/src/main/java/org/jose4j/keys/resolvers/JwksDecryptionKeyResolver.java
index 57f9b81..3297748 100644
--- a/src/main/java/org/jose4j/keys/resolvers/JwksDecryptionKeyResolver.java
+++ b/src/main/java/org/jose4j/keys/resolvers/JwksDecryptionKeyResolver.java
@@ -31,8 +31,9 @@ import java.util.List;
  */
 public class JwksDecryptionKeyResolver implements DecryptionKeyResolver
 {
-    private List<JsonWebKey> jsonWebKeys;
-    private DecryptionJwkSelector selector = new DecryptionJwkSelector();
+    private final List<JsonWebKey> jsonWebKeys;
+    private final DecryptionJwkSelector selector = new DecryptionJwkSelector();
+    boolean disambiguateWithAttemptDecrypt;
 
     public JwksDecryptionKeyResolver(List<JsonWebKey> jsonWebKeys)
     {
@@ -45,7 +46,26 @@ public class JwksDecryptionKeyResolver implements DecryptionKeyResolver
         JsonWebKey selected;
         try
         {
-            selected = selector.select(jwe, jsonWebKeys);
+            List<JsonWebKey> selectedList = selector.selectList(jwe, this.jsonWebKeys);
+            if (selectedList.isEmpty())
+            {
+                selected = null;
+            }
+            else if (selectedList.size() == 1 || !disambiguateWithAttemptDecrypt)
+            {
+                selected = selectedList.get(0);
+            }
+            else
+            {
+                selected = selector.attemptDecryptDisambiguate(jwe, selectedList);
+                if (selected == null)
+                {
+                    StringBuilder sb = new StringBuilder();
+                    sb.append("Unable to find a suitable key for JWE w/ header ").append(jwe.getHeaders().getFullHeaderAsJsonString());
+                    sb.append(" using attempted decryption to disambiguate from filtered candidate JWKs ").append(jsonWebKeys);
+                    throw new UnresolvableKeyException(sb.toString());
+                }
+            }
         }
         catch (JoseException e)
         {
@@ -65,4 +85,13 @@ public class JwksDecryptionKeyResolver implements DecryptionKeyResolver
 
         return selected instanceof PublicJsonWebKey ? ((PublicJsonWebKey) selected).getPrivateKey() : selected.getKey();
     }
+
+    /**
+     * Indicates whether to try decrypting to disambiguate when the normal key selection based on the JWE headers results in more than one key. Default is false.
+     * @param disambiguateWithAttemptDecrypt boolean indicating whether to use decrypting to disambiguate
+     */
+    public void setDisambiguateWithAttemptDecrypt(boolean disambiguateWithAttemptDecrypt)
+    {
+        this.disambiguateWithAttemptDecrypt = disambiguateWithAttemptDecrypt;
+    }
 }
diff --git a/src/test/java/org/jose4j/jws/DetachedContentTest.java b/src/test/java/org/jose4j/jws/DetachedContentTest.java
index 5e7ce03..e1b2c99 100644
--- a/src/test/java/org/jose4j/jws/DetachedContentTest.java
+++ b/src/test/java/org/jose4j/jws/DetachedContentTest.java
@@ -16,11 +16,15 @@
 
 package org.jose4j.jws;
 
+import org.jose4j.jwa.AlgorithmConstraints;
+import org.jose4j.jwk.PublicJsonWebKey;
 import org.jose4j.keys.ExampleEcKeysFromJws;
 import org.junit.Test;
 
-import static org.hamcrest.CoreMatchers.*;
-import static org.junit.Assert.*;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 /**
  *
@@ -58,4 +62,82 @@ public class DetachedContentTest
         jws.setKey(ExampleEcKeysFromJws.PUBLIC_256);
         assertFalse(jws.verifySignature());
     }
+
+    @Test
+    public void testVerifyDetachedUnencodedContentButSignatureOverEncoded() throws Exception {
+
+        // the detached payload was conveyed unencoded but the signature was traditional JWS over the encoded
+        // jose4j couldn't verify due to empty string / null mixup
+        // https://bitbucket.org/b_c/jose4j/issues/194/verifying-jws-with-detached-payload-using
+        // https://stackoverflow.com/questions/70380691/verifying-jws-with-detached-payload-using-jose4j-fails
+
+        String payload = "{\"paymentId\":\"d927a7c8cca3392907808ef2\",\"transferAmount\":1310,\"tippingAmount\":0,"
+                + "\"amount\":1310,\"totalAmount\":1310,\"description\":\"Invoice Payment\",\"reference\":\"0006-485\","
+                + "\"createdAt\":\"2021-12-16T13:41:08.726Z\",\"expireAt\":\"2031-12-16T23:53:08.726Z\",\"succeededAt\":\"2021-12-16T13:41:20.189Z\","
+                + "\"status\":\"SUCCEEDED\",\"debtor\":{\"name\":\"Koen\",\"iban\":\"*************24680\"},\"currency\":\"EUR\"}";
+
+        String signature = "eyJ0eXAiOiJKT1NFK0pTT04iLCJraWQiOiJlcy5zaWduYXR1cmUuZXh0LjIwMjIiLCJhbGciOiJFUzI1NiIsImh0d"
+                + "HBzOi8vcGF5Y29uaXEuY29tL2lhdCI6IjIwMjEtMTItMTZUMTM6NDE6MjAuMjA5NTU0WiIsImh0dHBzOi8vcGF5Y29uaXEuY29tL2p0aSI"
+                + "6IjIzZjVhNzVkMTNmYWMzOWEiLCJodHRwczovL3BheWNvbmlxLmNvbS9wYXRoIjoiaHR0cHM6Ly90ZXN0Mi5zb25ldGFzLmV1L2Z1Z2Evc"
+                + "mVzdC9wYXljb25pcS9pbnZvaWNlUGF5bWVudCIsImh0dHBzOi8vcGF5Y29uaXEuY29tL2lzcyI6IlBheWNvbmlxIiwiaHR0cHM6Ly9wYXl"
+                + "jb25pcS5jb20vc3ViIjoiNjFiMDcxNThkZjUwODkwMDA3ZGM3Y2NhIiwiY3JpdCI6WyJodHRwczovL3BheWNvbmlxLmNvbS9pYXQiLCJod"
+                + "HRwczovL3BheWNvbmlxLmNvbS9qdGkiLCJodHRwczovL3BheWNvbmlxLmNvbS9wYXRoIiwiaHR0cHM6Ly9wYXljb25pcS5jb20vaXNzIiw"
+                + "iaHR0cHM6Ly9wYXljb25pcS5jb20vc3ViIl19..AZCpJ_3M8fKyK_sQ0XS9ifdCnZUiQHReQ7owWhVdrfs90mFj66z9XEh-Fcl_IteSUgR"
+                + "JU7-TrLDdEfrISvG0lw";
+
+        String[] critHeaders = {
+                "https://payconiq.com/sub",
+                "https://payconiq.com/iss",
+                "https://payconiq.com/iat",
+                "https://payconiq.com/jti",
+                "https://payconiq.com/path"
+        };
+
+        String key = "{"
+                + "\"kty\": \"EC\","
+                + "\"use\": \"sig\","
+                + "\"x5t#S256\": \"IZOqCxLESbQkCaObdW1kxMPgV5VFGb9nFkjiwL0G_eg\","
+                + "\"crv\": \"P-256\","
+                + "\"kid\": \"es.signature.ext.2022\","
+                + "\"alg\": \"ES256\","
+                + "\"x5c\": ["
+                + "\"MIIE1zCCBH2gAwIBAgIQHzgeQOjemgrfp6IwTS5XfzAKBggqhkjOPQQDAjCBjzELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTcwNQYDVQQDEy5TZWN0aWdvIEVDQyBEb21haW4gVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENBMB4XDTIxMTEyMzAwMDAwMFoXDTIyMTIyNDIzNTk1OVowKDEmMCQGA1UEAxMdZXMuc2lnbmF0dXJlLmV4dC5wYXljb25pcS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARIpLe02lsuMs6G1lQQRw3Zo4GlBwxi1h7EDD6GC9MxYRkkxOQMrJ1UKD3ni4dXcCZjHyv2GGvWhNICOaCso9Elo4IDHzCCAxswHwYDVR0jBBgwFoAU9oUKOxGG4QR9DqoLLNLuzGR7e64wHQYDVR0OBBYEFHUsvJY0jGLPbsoGZeOmkk09+ADEMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBJBgNVHSAEQjBAMDQGCysGAQQBsjEBAgIHMCUwIwYIKwYBBQUHAgEWF2h0dHBzOi8vc2VjdGlnby5jb20vQ1BTMAgGBmeBDAECATCBhAYIKwYBBQUHAQEEeDB2ME8GCCsGAQUFBzAChkNodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3RpZ29FQ0NEb21haW5WYWxpZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3J0MCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0aWdvLmNvbTBLBgNVHREERDBCgh1lcy5zaWduYXR1cmUuZXh0LnBheWNvbmlxLmNvbYIhd3d3LmVzLnNpZ25hdHVyZS5leHQucGF5Y29uaXEuY29tMIIBewYKKwYBBAHWeQIEAgSCAWsEggFnAWUAdQBGpVXrdfqRIDC1oolp9PN9ESxBdL79SbiFq/L8cP5tRwAAAX1MZuRtAAAEAwBGMEQCIErmMHlQjPe/aNTo08NiFGS2hlKeBU5Ubrl9OG7myLWcAiB4bWXL8HOl2oNVci3Cv0RMnNTyMHIrAm8Lw9QQq/UxTQB1AEHIyrHfIkZKEMahOglCh15OMYsbA+vrS8do8JBilgb2AAABfUxm5DUAAAQDAEYwRAIgNEbgqCHIAjLqhRGBmiHRAqNwX5qI1GSlfAbqVq4V/W0CIHRCmucjmXpbVKzPsOfJ6RBPHWSUJJSjiGLf1QTtvliDAHUAKXm+8J45OSHwVnOfY6V35b5XfZxgCvj5TV0mXCVdx4QAAAF9TGbj/QAABAMARjBEAiAlPQGU1X34G+wtrYEpGFodWifIfxfeOwKx9o3qjVr4LAIgUQenz7z8a0zIC5XATCAwEG3uXnbATrl+ss5cu6YqvPowCgYIKoZIzj0EAwIDSAAwRQIhAN5vKyEhzWAj6Wc6bhr8l9YXIGn4e4dNVSYeHcRoK0AkAiAhhXJkG+SzWyp/bFJeCfXbnWw59mww9GOOkoNizKCG6w==\","
+                + "\"MIIDqDCCAy6gAwIBAgIRAPNkTmtuAFAjfglGvXvh9R0wCgYIKoZIzj0EAwMwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtKZXJzZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMS4wLAYDVQQDEyVVU0VSVHJ1c3QgRUNDIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTE4MTEwMjAwMDAwMFoXDTMwMTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDE3MDUGA1UEAxMuU2VjdGlnbyBFQ0MgRG9tYWluIFZhbGlkYXRpb24gU2VjdXJlIFNlcnZlciBDQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABHkYk8qfbZ5sVwAjBTcLXw9YWsTef1Wj6R7W2SUKiKAgSh16TwUwimNJE4xkIQeV/To14UrOkPAY9z2vaKb71EijggFuMIIBajAfBgNVHSMEGDAWgBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAdBgNVHQ4EFgQU9oUKOxGG4QR9DqoLLNLuzGR7e64wDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBsGA1UdIAQUMBIwBgYEVR0gADAIBgZngQwBAgEwUAYDVR0fBEkwRzBFoEOgQYY/aHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VTRVJUcnVzdEVDQ0NlcnRpZmljYXRpb25BdXRob3JpdHkuY3JsMHYGCCsGAQUFBwEBBGowaDA/BggrBgEFBQcwAoYzaHR0cDovL2NydC51c2VydHJ1c3QuY29tL1VTRVJUcnVzdEVDQ0FkZFRydXN0Q0EuY3J0MCUGCCsGAQUFBzABhhlodHRwOi8vb2NzcC51c2VydHJ1c3QuY29tMAoGCCqGSM49BAMDA2gAMGUCMEvnx3FcsVwJbZpCYF9z6fDWJtS1UVRscS0chWBNKPFNpvDKdrdKRe+oAkr2jU+ubgIxAODheSr2XhcA7oz9HmedGdMhlrd94ToKFbZl+/OnFFzqnvOhcjHvClECEQcKmc8fmA==\","
+                + "\"MIID0zCCArugAwIBAgIQVmcdBOpPmUxvEIFHWdJ1lDANBgkqhkiG9w0BAQwFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTE5MDMxMjAwMDAwMFoXDTI4MTIzMTIzNTk1OVowgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtKZXJzZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMS4wLAYDVQQDEyVVU0VSVHJ1c3QgRUNDIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEGqxUWqn5aCPnetUkb1PGWthLq8bVttHmc3Gu3ZzWDGH926CJA7gFFOxXzu5dP+Ihs8731Ip54KODfi2X0GHE8ZncJZFjq38wo7Rw4sehM5zzvy5cU7Ffs30yf4o043l5o4HyMIHvMB8GA1UdIwQYMBaAFKARCiM+lvEH7OKvKe+CpX/QMKS0MB0GA1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zARBgNVHSAECjAIMAYGBFUdIAAwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wDQYJKoZIhvcNAQEMBQADggEBABns652JLCALBIAdGN5CmXKZFjK9Dpx1WywV4ilAbe7/ctvbq5AfjJXyij0IckKJUAfiORVsAYfZFhr1wHUrxeZWEQff2Ji8fJ8ZOd+LygBkc7xGEJuTI42+FsMuCIKchjN0djsoTI0DQoWz4rIjQtUfenVqGtF8qmchxDM6OW1TyaLtYiKou+JVbJlsQ2uRl9EMC5MCHdK8aXdJ5htN978UeAOwproLtOGFfy/cQjutdAFI3tZs4RmYCV4Ks2dH/hzg1cEo70qLRDEmBDeNiXQ2Lu+lIg+DdEmSx/cQwgwp+7e9un/jX9Wf8qn0dNW44bOwgeThpWOjzOoEeJBuv/c=\","
+                + "\"MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLzRt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==\""
+                + "],"
+                + "\"x\": \"SKS3tNpbLjLOhtZUEEcN2aOBpQcMYtYexAw-hgvTMWE\","
+                + "\"y\": \"GSTE5AysnVQoPeeLh1dwJmMfK_YYa9aE0gI5oKyj0SU\""
+                + "}";
+
+        JsonWebSignature jws = new JsonWebSignature();
+        PublicJsonWebKey jwk = PublicJsonWebKey.Factory.newPublicJwk(key);
+        jws.setAlgorithmConstraints(new AlgorithmConstraints(AlgorithmConstraints.ConstraintType.PERMIT,
+                AlgorithmIdentifiers.ECDSA_USING_P256_CURVE_AND_SHA256));
+        jws.setKnownCriticalHeaders(critHeaders);
+        jws.setCompactSerialization(signature);
+        jws.setPayload(payload);
+        jws.setKey(jwk.getPublicKey());
+        boolean result = jws.verifySignature();
+        assertTrue(jws.verifySignature());
+    }
+
+    @Test
+    public void testSomeDetachedUnencodedContentButSignatureOverEncoded() throws Exception
+    {
+        String payload = "Grace? She passed away 30 years ago!";
+
+        JsonWebSignature jws = new JsonWebSignature();
+        jws.setPayload(payload);
+        jws.setKey(ExampleEcKeysFromJws.PRIVATE_256);
+        jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.ECDSA_USING_P256_CURVE_AND_SHA256);
+        String detachedContentCompactSerialization = jws.getDetachedContentCompactSerialization();
+
+        jws = new JsonWebSignature();
+        jws.setCompactSerialization(detachedContentCompactSerialization);
+        jws.setPayload(payload);
+        jws.setKey(ExampleEcKeysFromJws.PUBLIC_256);
+        assertTrue(jws.verifySignature());
+        assertThat(payload, equalTo(jws.getPayload()));
+    }
 }
diff --git a/src/test/java/org/jose4j/jws/EcdsaUsingShaEdgesTest.java b/src/test/java/org/jose4j/jws/EcdsaUsingShaEdgesTest.java
new file mode 100644
index 0000000..8eb1d76
--- /dev/null
+++ b/src/test/java/org/jose4j/jws/EcdsaUsingShaEdgesTest.java
@@ -0,0 +1,274 @@
+package org.jose4j.jws;
+
+import org.bouncycastle.util.encoders.Hex;
+import org.jose4j.base64url.Base64Url;
+import org.jose4j.jwk.PublicJsonWebKey;
+import org.jose4j.keys.ExampleEcKeysFromJws;
+import org.jose4j.lang.JoseException;
+import org.junit.Test;
+
+import java.security.PublicKey;
+
+import static org.junit.Assert.assertFalse;
+
+public class EcdsaUsingShaEdgesTest
+{
+    @Test
+    public void zeros() throws Exception
+    {
+        expectInvalidSignature("eyJhbGciOiJFUzI1NiJ9.RXZlcnlvbmUgcHJldGVuZHM.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", ExampleEcKeysFromJws.PUBLIC_256);
+    }
+
+    @Test
+    public void sameAsOrder() throws Exception
+    {
+        // https://twitter.com/phLaul/status/1517209015649914881
+        expectInvalidSignature("eyJhbGciOiJFUzI1NiJ9.RXZlcnlvbmUgcHJldGVuZHM._____wAAAAD__________7zm-q2nF56E87nKwvxjJVH_____AAAAAP__________vOb6racXnoTzucrC_GMlUQ", ExampleEcKeysFromJws.PUBLIC_256);
+    }
+
+    @Test
+    public void someOfTheWycheproofStuffP256() throws Exception
+    {
+        // a few of these would verify with java 17.0.2
+        PublicJsonWebKey jwk = PublicJsonWebKey.Factory.newPublicJwk("{\n" +
+                "        \"crv\" : \"P-256\",\n" +
+                "        \"kid\" : \"none\",\n" +
+                "        \"kty\" : \"EC\",\n" +
+                "        \"x\" : \"KSexBRK64-3c_kZ4KBKLrSkDJpkZ9whgacjE32xzKDg\",\n" +
+                "        \"y\" : \"x3h5ZOqsAOWSH7FJimD0YGdms9loUAFVjRqXTnNBUT4\"\n" +
+                "      }");
+
+        String[] hexSigs =
+        {
+            "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+            "012ba3a8bd6b94d5ed80a6d9d1190a436ebccc0833490686deac8635bcb9bf536900b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db",
+            "d45c5740946b2a147f59262ee6f5bc90bd01ed280528b62b3aed5fc93f06f739b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db",
+            "012ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1800b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db",
+            "d45c5741946b2a137f59262ee6f5bc91001af27a5e1117a64733950642a3d1e8b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db",
+            "002ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1801b329f478a2bbd0a6c384ee1493b1f518276e0e4a5375928d6fcd160c11cb6d2c",
+            "002ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e1801b329f479a2bbd0a5c384ee1493b1f5186a87139cac5df4087c134b49156847db",
+            "2ba3a8be6b94d5ec80a6d9d1190a436effe50d85a1eee859b8cc6af9bd5c2e184cd60b865d442f5a3c7b11eb6c4e0ae79578ec6353a20bf783ecb4b6ea97b825",
+            "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+            "0000000000000000000000000000000000000000000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
+            "0000000000000000000000000000000000000000000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550",
+            "0000000000000000000000000000000000000000000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552",
+            "0000000000000000000000000000000000000000000000000000000000000000ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
+            "0000000000000000000000000000000000000000000000000000000000000000ffffffff00000001000000000000000000000001000000000000000000000000",
+            "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000",
+            "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001",
+            "0000000000000000000000000000000000000000000000000000000000000001ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
+            "0000000000000000000000000000000000000000000000000000000000000001ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550",
+            "0000000000000000000000000000000000000000000000000000000000000001ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552",
+            "0000000000000000000000000000000000000000000000000000000000000001ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
+            "0000000000000000000000000000000000000000000000000000000000000001ffffffff00000001000000000000000000000001000000000000000000000000",
+            "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325510000000000000000000000000000000000000000000000000000000000000000",
+            "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325510000000000000000000000000000000000000000000000000000000000000001",
+            "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
+            "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550",
+            "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552",
+            "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
+            "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551ffffffff00000001000000000000000000000001000000000000000000000000",
+            "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325500000000000000000000000000000000000000000000000000000000000000000",
+            "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325500000000000000000000000000000000000000000000000000000000000000001",
+            "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
+            "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550",
+            "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552",
+            "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
+            "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550ffffffff00000001000000000000000000000001000000000000000000000000",
+            "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325520000000000000000000000000000000000000000000000000000000000000000",
+            "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325520000000000000000000000000000000000000000000000000000000000000001",
+            "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
+            "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550",
+            "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552",
+            "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
+            "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552ffffffff00000001000000000000000000000001000000000000000000000000",
+            "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000",
+            "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000001",
+            "ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
+            "ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550",
+            "ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552",
+            "ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
+            "ffffffff00000001000000000000000000000000ffffffffffffffffffffffffffffffff00000001000000000000000000000001000000000000000000000000",
+            "ffffffff000000010000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+            "ffffffff000000010000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+            "ffffffff00000001000000000000000000000001000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
+            "ffffffff00000001000000000000000000000001000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550",
+            "ffffffff00000001000000000000000000000001000000000000000000000000ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552",
+            "ffffffff00000001000000000000000000000001000000000000000000000000ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
+            "ffffffff00000001000000000000000000000001000000000000000000000000ffffffff00000001000000000000000000000001000000000000000000000000"
+        };
+
+        for (String hexSig : hexSigs)
+        {
+            String encodedSig = Base64Url.encode(Hex.decode(hexSig));
+            expectInvalidSignature("eyJhbGciOiJFUzI1NiJ9.RXZlcnlvbmUgcHJldGVuZHM." + encodedSig, jwk.getPublicKey());
+        }
+    }
+
+    @Test
+    public void someOfTheWycheproofStuffP384() throws Exception
+    {
+        // a few of these would verify with java 17.0.2
+        PublicJsonWebKey jwk = PublicJsonWebKey.Factory.newPublicJwk("{\n" +
+                "        \"crv\" : \"P-384\",\n" +
+                "        \"kid\" : \"none\",\n" +
+                "        \"kty\" : \"EC\",\n" +
+                "        \"x\" : \"LaV92hCJJ2pUP5_9rAv_DZdsrXHrcoDn2b_Z_uS9svIPR_-IgnQ4l3LZjMV1ITiq\",\n" +
+                "        \"y\" : \"S20FTWnc8-JexJ34cHFeNIg7GDYZfXb4rZYuePZXG7x0B7DWCR-eTYjwFCdEBhdP\"\n" +
+                "      }");
+
+        String[] hexSigs =
+        {
+            "0112b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19a25617aad7485e6312a8589714f647acf7a94cffbe8a724a00e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82",
+            "ed4cf541094ab8901949ed51aa83fbda99e1d94bb4e401e5ec7083591125fd5b9d8bc2cd7c6b0748e22ee5d5daffe09ce7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82",
+            "0112b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d700e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82",
+            "ed4cf541094ab8901949ed51aa83fbda99e1d94bb4e401e6250d35d71ceecf7c4571b51b33ba5fcdf542cc6b0e3ab729e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82",
+            "0012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d701e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc5f8fc6adfda650a86aa74b95adbd6874b3cd8dde6cc0798f5",
+            "0012b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d701e7bf25603e2d07076ff30b7a2abec473da8b11c572b35fc631991d5de62ddca7525aaba89325dfd04fecc47bff426f82",
+            "12b30abef6b5476fe6b612ae557c0425661e26b44b1bfe19daf2ca28e3113083ba8e4ae4cc45a0320abd3394f1c548d71840da9fc1d2f8f8900cf485d5413b8c2574ee3a8d4ca039ce66e2a219d22358ada554576cda202fb0133b8400bd907e",
+            "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+            "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+            "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973",
+            "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52972",
+            "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52974",
+            "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff",
+            "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff000000000000000100000000",
+            "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+            "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+            "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973",
+            "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52972",
+            "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52974",
+            "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff",
+            "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff000000000000000100000000",
+            "ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+            "ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+            "ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973",
+            "ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52972",
+            "ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52974",
+            "ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff",
+            "ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff000000000000000100000000",
+            "ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52972000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+            "ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52972000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+            "ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52972ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973",
+            "ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52972ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52972",
+            "ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52972ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52974",
+            "ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52972fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff",
+            "ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52972fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff000000000000000100000000",
+            "ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52974000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+            "ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52974000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+            "ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52974ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973",
+            "ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52974ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52972",
+            "ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52974ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52974",
+            "ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52974fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff",
+            "ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52974fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff000000000000000100000000",
+            "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+            "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+            "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973",
+            "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52972",
+            "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52974",
+            "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff",
+            "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff000000000000000100000000",
+            "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+            "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+            "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff000000000000000100000000ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973",
+            "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff000000000000000100000000ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52972",
+            "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff000000000000000100000000ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52974",
+            "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff000000000000000100000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff",
+            "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff000000000000000100000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff000000000000000100000000",
+        };
+
+        for (String hexSig : hexSigs)
+        {
+            String encodedSig = Base64Url.encode(Hex.decode(hexSig));
+            expectInvalidSignature("eyJhbGciOiJFUzM4NCJ9.RXZlcnlvbmUgcHJldGVuZHM." + encodedSig, jwk.getPublicKey());
+        }
+    }
+
+    @Test
+    public void someOfTheWycheproofStuffP521() throws Exception
+    {
+        // a few of these would verify with java 17.0.2
+        PublicJsonWebKey jwk = PublicJsonWebKey.Factory.newPublicJwk("{\n" +
+                "        \"crv\" : \"P-521\",\n" +
+                "        \"kid\" : \"none\",\n" +
+                "        \"kty\" : \"EC\",\n" +
+                "        \"x\" : \"AFxkV-wIjVMvSCCTllrlPM0H5VbtWeKvlFzYx6lcHGRPilaoqKPNdzkt3YYeipJNrJnGkGkJO9UqUvpsVgBKB0UI\",\n" +
+                "        \"y\" : \"AHh41tQuS03R6cBpbLPhn2MDPD205g1HMlmz6-B5qvCphu5hd_ghenjGi4E_fhSaTlb9lWLAf-09iVlC19EBy4P2\"\n" +
+                "      }");
+
+        String[] hexSigs =
+        {
+            "024e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbe97b3367122fa4a20584c271233f3ec3b7f7b31b0faa4d340b92a6b0d5cd17ea4e0028b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1",
+            "01b1bddc11bc17347621c4ecc6003d861a7d07d3854f08e4421bc241c8b538a0040b27d9a7f54eba8ad17ad5916eaed487e87fb8786168eb5b51e438bd675558ddc40028b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1",
+            "024e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf86450028b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1",
+            "01b1bddc11bc17347621c4ecc6003d861a7d07d3854f08e4421bc241c8b538a00410d65320718f8af465fb099025b7cae2184402aea8df4f13a328c90648c42079bb0028b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1",
+            "004e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf86450228b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba09a7b6ac4ecd0410b4722ca75ba197a403a0a1f9ee0e7b391b0649fda1d3969eeca",
+            "004e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf86450228b5d0926a4172b349b0fd2e929487a5edb94b142df923a697e7446acdacdba0a029e43d69111174dba2fe747122709a69ce69d5285e174a01a93022fea8318ac1",
+            "004e4223ee43e8cb89de3b1339ffc279e582f82c7ab0f71bbde43dbe374ac75ffbef29acdf8e70750b9a04f66fda48351de7bbfd515720b0ec5cd736f9b73bdf864501d74a2f6d95be8d4cb64f02d16d6b785a1246b4ebd206dc596818bb953253245f5fd61bc296eeee8b245d018b8edd8f659631962ad7a1e8b5fe56cfdd0157ce753f",
+            "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+            "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+            "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
+            "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386408",
+            "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e9138640a",
+            "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+            "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+            "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+            "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+            "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
+            "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386408",
+            "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e9138640a",
+            "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+            "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+            "01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+            "01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+            "01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e9138640901fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
+            "01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e9138640901fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386408",
+            "01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e9138640901fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e9138640a",
+            "01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e9138640901ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+            "01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+            "01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386408000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+            "01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386408000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+            "01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e9138640801fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
+            "01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e9138640801fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386408",
+            "01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e9138640801fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e9138640a",
+            "01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e9138640801ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+            "01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386408020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+            "01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e9138640a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+            "01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e9138640a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+            "01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e9138640a01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
+            "01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e9138640a01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386408",
+            "01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e9138640a01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e9138640a",
+            "01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e9138640a01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+            "01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e9138640a020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+            "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+            "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+            "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
+            "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386408",
+            "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e9138640a",
+            "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+            "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+            "020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+            "020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+            "02000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
+            "02000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386408",
+            "02000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e9138640a",
+            "02000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+            "020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+        };
+
+        for (String hexSig : hexSigs)
+        {
+            String encodedSig = Base64Url.encode(Hex.decode(hexSig));
+            expectInvalidSignature("eyJhbGciOiJFUzUxMiJ9.ZmZz." + encodedSig, jwk.getPublicKey());
+        }
+    }
+
+    void expectInvalidSignature(String jws, PublicKey key) throws JoseException
+    {
+        JsonWebSignature verifyingJws = new JsonWebSignature();
+        verifyingJws.setCompactSerialization(jws);
+        verifyingJws.setKey(key);
+        boolean verifySignature = verifyingJws.verifySignature();
+        assertFalse(jws + " should not verify!", verifySignature);
+    }
+}
diff --git a/src/test/java/org/jose4j/jwt/consumer/JwksDecryptionKeyResolverUsingJwtConsumerTest.java b/src/test/java/org/jose4j/jwt/consumer/JwksDecryptionKeyResolverUsingJwtConsumerTest.java
index a30b800..fa86e24 100644
--- a/src/test/java/org/jose4j/jwt/consumer/JwksDecryptionKeyResolverUsingJwtConsumerTest.java
+++ b/src/test/java/org/jose4j/jwt/consumer/JwksDecryptionKeyResolverUsingJwtConsumerTest.java
@@ -16,20 +16,31 @@
 package org.jose4j.jwt.consumer;
 
 import org.hamcrest.CoreMatchers;
+import org.jose4j.jwa.JceProviderTestSupport;
+import org.jose4j.jwe.ContentEncryptionAlgorithmIdentifiers;
+import org.jose4j.jwe.JsonWebEncryption;
+import org.jose4j.jwe.KeyManagementAlgorithmIdentifiers;
+import org.jose4j.jwk.JsonWebKey;
 import org.jose4j.jwk.JsonWebKeySet;
+import org.jose4j.jwk.OctJwkGenerator;
+import org.jose4j.jwk.OctetSequenceJsonWebKey;
 import org.jose4j.jwt.JwtClaims;
 import org.jose4j.jwt.MalformedClaimException;
 import org.jose4j.jwt.NumericDate;
 import org.jose4j.keys.resolvers.JwksDecryptionKeyResolver;
 import org.jose4j.keys.resolvers.JwksVerificationKeyResolver;
 import org.jose4j.lang.JoseException;
-import org.junit.Assert;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.junit.Assert.assertThat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.fail;
 
 /**
@@ -64,8 +75,8 @@ public class JwksDecryptionKeyResolverUsingJwtConsumerTest
                 .build();
 
         JwtContext jwtCtx = jwtConsumer.process(jwt);
-        Assert.assertThat(jwtCtx.getJoseObjects().size(), CoreMatchers.equalTo(1));
-        Assert.assertThat(jwtCtx.getJwtClaims().getSubject(), CoreMatchers.equalTo("Scott Tomilson, not Tomlinson"));
+        assertThat(jwtCtx.getJoseObjects().size(), CoreMatchers.equalTo(1));
+        assertThat(jwtCtx.getJwtClaims().getSubject(), CoreMatchers.equalTo("Scott Tomilson, not Tomlinson"));
 
         String badJwt = "eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoiZGV1eCJ9" +
                 "." +
@@ -132,8 +143,8 @@ public class JwksDecryptionKeyResolverUsingJwtConsumerTest
                 .build();
 
         JwtContext jwtCtx = jwtConsumer.process(jwt);
-        Assert.assertThat(jwtCtx.getJoseObjects().size(), CoreMatchers.equalTo(1));
-        Assert.assertThat(jwtCtx.getJwtClaims().getSubject(), CoreMatchers.equalTo("Scott Tomilson, not Tomlinson"));
+        assertThat(jwtCtx.getJoseObjects().size(), CoreMatchers.equalTo(1));
+        assertThat(jwtCtx.getJwtClaims().getSubject(), CoreMatchers.equalTo("Scott Tomilson, not Tomlinson"));
     }
 
     @Test
@@ -173,4 +184,188 @@ public class JwksDecryptionKeyResolverUsingJwtConsumerTest
         assertThat("ABOUT", equalTo(claims.getSubject()));
     }
 
+    @Test
+    public void asymmetricDecryptionKeysWithDisambiguate() throws Exception
+    {
+//        RsaJsonWebKey rsaJsonWebKey1 = RsaJwkGenerator.generateJwk(2048);
+//        rsaJsonWebKey1.setUse(Use.ENCRYPTION);
+//        rsaJsonWebKey1.setKeyId("r1");
+//        RsaJsonWebKey rsaJsonWebKey2 = RsaJwkGenerator.generateJwk(2048);
+//        rsaJsonWebKey2.setUse(Use.ENCRYPTION);
+//        rsaJsonWebKey2.setKeyId("r2");
+//        EllipticCurveJsonWebKey ellipticCurveJsonWebKey1 = EcJwkGenerator.generateJwk(EllipticCurves.P256);
+//        ellipticCurveJsonWebKey1.setUse(Use.ENCRYPTION);
+//        ellipticCurveJsonWebKey1.setKeyId("e1");
+//        EllipticCurveJsonWebKey ellipticCurveJsonWebKey2 = EcJwkGenerator.generateJwk(EllipticCurves.P256);
+//        ellipticCurveJsonWebKey2.setUse(Use.ENCRYPTION);
+//        ellipticCurveJsonWebKey2.setKeyId("e2");
+//        JsonWebKeySet jsonWebKeySet = new JsonWebKeySet(rsaJsonWebKey1, rsaJsonWebKey2, ellipticCurveJsonWebKey1, ellipticCurveJsonWebKey2);
+//        System.out.println(jsonWebKeySet.toJson(JsonWebKey.OutputControlLevel.INCLUDE_PRIVATE));
+
+//        RsaJsonWebKey rsaJsonWebKey3 = RsaJwkGenerator.generateJwk(4096);
+//        rsaJsonWebKey3.setUse(Use.ENCRYPTION);
+//        rsaJsonWebKey3.setKeyId("r3");
+//
+//        RsaJsonWebKey rsaJsonWebKey4 = RsaJwkGenerator.generateJwk(3072);
+//        rsaJsonWebKey4.setUse(Use.ENCRYPTION);
+//        rsaJsonWebKey4.setKeyId("r4");
+
+//        System.out.println(rsaJsonWebKey3.toJson(JsonWebKey.OutputControlLevel.INCLUDE_PRIVATE));
+//        System.out.println(rsaJsonWebKey4.toJson(JsonWebKey.OutputControlLevel.INCLUDE_PRIVATE));
+
+
+        JsonWebKeySet jsonWebKeySet = new JsonWebKeySet("{\"keys\":[" +
+                "{\"kty\":\"RSA\",\"kid\":\"r1\",\"use\":\"enc\",\"n\":\"lFZ04QwtWu_hHgqlry40DuIhVZyl6ci6FzyLfkeHLH8xfCDLR-rvslxX-Ub3teVnPjZYdUFlZztuDo5kOFsF7TvUQMJhx00VZ6qugm-4LDSJ93ioGuo37vNDjMYBs0dEw_xV38e_m_Jo-oTJZN8xfZFroiR0cRNzac2e98lPa-TCxtOCuVp8Q8ro1Y6nC_1g51iY3nZXHfELX4vUxSh-4z7I0VkzCREQNYx-iKWw6MqEl2qG2mohiwlRexphf-1--8RuJ7FgubewzFv6dP_vCO9cYGi2qB0Gw6b9u8Jb60JYM7xLT3wGTQNfepiXQWESbVorxYiwZODP7d0tteD-eQ\",\"e\":\"AQAB\",\"d\":\"CTA3yi7ialUciStYqvq-L8PTE8YBwvLzj_fonhhZJ6jzTECNxvUnBtHQgzjhpCtDE2fzX8P-v3-_Z_hq_dCpk9HWanJ_8wPz1PmOGLdJ3bcdaq5XH1-tukfoQcKMHWpHOKqbOSLa3BKObSInhW-L1b7Zv2_ppI1zYzTg6XFXUZQAUzB9anvdQDiQRLTeLhCW3zZND-WtjrycvsgoIFApCwfWQMsv4Uhi7tedgwRt7_EBJcSO9vyGlE6Mf0tJCzCuwWWsfKbxc7NutR6y9Wh2_rGDgyzAxxT2v8E_CjmsuhYwz_a4PD5LcrpMYBq1_pTar-_ql-qMwDrsn682UUoRAQ\",\"p\":\"yTmQMaGX1Ja2z8wllKMc2QAdk04pBBRyQyNb3U2_B5hCpz1azvEC1jtgAFJaV9jW5K9b5M4sjdaA8HvWFcPMLtAU0T-e3INNpoW-mRTw71gZDbL_eW9bJBjBTUw2fltUQXNG1MrIw5aVsmEwkO3OJUyIIA0fVloLPVTczYG_pEE\",\"q\":\"vLdued0wjqKXJCZxHpW6ij_CNZKm1_ohApsJ6iF41KTjJAd-1lUlUzgY_As6Ck5a6hz8E_94mUv3ykn6NVFiLQIyGGyiCfU3J6jO4QmS7jZu75FtJuh-7J4Yj8V8eztupaPz69DgjvwQlxjFMUjk_AYjhRf5DzOf0lCd33ZqbDk\",\"dp\":\"f1tudusmlIebRuOXeX7POEzJaz0R2qIyO2n6r5OQb3cf4IeFnOqPeBX2Sd3VjjoQsIaIa8VOD6uOyiYmtnnJFmvecR2KJ1j3YYjOvEazw1iH6tK6vRoMnkkItyqgZtLY_d-_GdkKvjfloRPAUEoiqhrJITgM-HNfH79BTNRs_cE\",\"dq\":\"r_9iSMTAREXeLxiq5ps9HTHZLZ1XfJUJtCRjWrdcuPQN4cwbvkgqRzJKGsVdm773it79OKlJD66JqV7UumTr6o3hqmWluSO4DISia71CCmc5jrNR2Ld7p7DJt0u2jDchOdlt4r8qri7mSgQP46bX5zLSbY2t-T9sDfihQ4ZsOgE\",\"qi\":\"tvxPXVg0igyHL6Rqr7qUilqyG7oCZU3ycXxjuXqWMkhw1ISz7RlyBouOLjYGEaxDFVyVtLj8RIUr4Hks-q7nZnD80yik-JZdN-BsQYU2xaGGDUVJPYt7TiHeRadx_68DxQKqlMl7N0c6RVfcXWdTlRSWIPYNgYqjavRzC15pF-E\"}," +
+                "{\"kty\":\"RSA\",\"kid\":\"r2\",\"use\":\"enc\",\"n\":\"yzFYB2Nqp5Wb34XQUBGRR33tp1jPVds46D3xwmTXPqjsbr4LMQqPWghtN_qE2bHldPJ9RJUk-i3UxnTAwR1bKLaCj6Aip_blZ4z_wK6IUIkJZk2nPD75YyhTpE9CqoI26lL2KBjMj3gn3cIxHi22BdGshppUbaf-ogH18LQ1bStM63uiflX44ud7GT4JVGaBczoad_cr-R1hs4kWZNdJrzBh7aPxebYnbAVd2CTeyXGYr_GIiq_sgtaBBISGoggruY5r-fva3R4YnhoTnmNeFOLDb99bzDPHbWhyjJ5nqBx7yaw1mT9uBnWno-h423bAT81TvXOJ2ogZ-jsYigx6xw\",\"e\":\"AQAB\",\"d\":\"Bf22Ib74Vb6fMkT-HQ5CNqsWMcP4QQjOBxL504h-TDZWL6G3hMJR8w6ijG783HUBVfm8YHmhSyXEy0vapGxa1BAljgSOYQjHlM5fJW2VTq1BCLIrcdGi2sianBKg3ZQp-Fi_3J4hPJhcseOC5-fjIQ1178tnHTXsgmxaYGF_3cXGkTiEg2xyph-eALczZlOA9_NitCySSO2R8tHAxpSqLujUb1tWvvAffGPu1pW2eJSDb9E2URRVX33yiGGbMNgFoMduBUUYiUKOBeq_zsGhuSnLqnfDbkIlhWiKfj-FRXPR72L9gJpZsiX_Tk_YZbxr3CphguL1_isvvCDgcPrmEQ\",\"p\":\"-KnLj5-Pyvgj-nUmpNEcY6TVrewK-GafZ53Cdo9-ko0cjt5CeW-y04JjUY3vTJRmFUNzqwj5LaYTDx7MJELCv9MiYB-x2LuAwKcfS8Pua1uyNusu6JraS_uRbR2JQVZ36DvNEBo57geRUZFCAYt2-d1WIXexQqXoXTNQ0P662E8\",\"q\":\"0TAZvdMIUpVG_x4Uo65nOTbJHLfTf7pBiYMGZuj74GQ6ggAWP9_EvW7azvhlCVu7W_0TjXLgxVU8WpTBUTjpU_J4ZMnB7jY5xImq7il9lZJCaZiubpjfzehb9UyMDMwtSnwhAT_6urUj0sk8KloA43ipDXN9tmKdoWZXxFE_IAk\",\"dp\":\"v7cpmrIKyxJFqvRntusCWFDd7hnu21VD0T9wjrhTfeoN-pih576WwTvmFxq3RPOlQP-gTl28v9UrHJ1CBzLxs7O07SeClvb5bY9sMZ3-VAd-f5kTsYKyi6KJnPcIu7dO-14f3CpcP4jWIW081rQQJtTfcy41HI2NeU33IStEI0E\",\"dq\":\"a7bK6nXJ6Uw4fJEuq4HYYRuWvxTg8PolWPuAxmjdmZPClMIastU0Zx63yK8ax5DWju1nrgQjPTlAlJvYV0xoyPMnjy5cj56YbF0_CNeQdP4U-G7IEubhBxPIlizOSKCyCZKVJCGfp5gyVA2Oz3f80SSGWAjKCKoK5NrgApSbXpE\",\"qi\":\"b3MC0KYMSuw2-FlUbVwUV6CTWfeEoz0iFQnfKNgiPpzz99NAfLeUaQQ2tjYGFUwLA5vMi4Rf1YF6gxPAYfLpkn2oKvlOqEn7go1pkbHMiQrC6kOG6Ubgek2h47sa0KUEkT91eKZa29fb4qcMHW4TJuR-IGYzJ532zpEReSk2oek\"}," +
+                "{\"kty\":\"RSA\",\"kid\":\"r3\",\"use\":\"enc\",\"n\":\"pkTznDIyNrI9wvfoFqv3yZpHv5PBeSXxdvOIKtsrKTSXxgDqjfn3jS4CiZidUjW1TzwwkYRZYU3Ei-M7qecudUs1QFdoBUNyd7V_X-ueToD1K-JvQCCrb74bzQWHVfsb2bRfuLw3Tyw3JwnWU3Q-P7OP08INyitwFw9Oz5DvKovtuOyAh3-CT8eSXcPMy2LQTt7WW8h2YeMq1EvndAc67ohiz-q3u2Qqwbbyv-p237mL_90JLE4xMBnLNey4FDjtXbXIq8T8QbvGyn4Dc67ZxH4-izAxi_siA_3z0H7oTYRaeNL4JuNqhoB0R4CgThfofdGVGZVWPyyowzSI-7nxbMHYNNse96wDnbTTKC8pP-qDjExRYjzm4iNueaMzzcq3wAIpR5z2tZp1oULOo43R0kcXC51sKrenJWnqIaIj_WsENRAWWHsrh5IycgySWyytaGVgQHaeBagYJHzRcrhWk10e81M8oMtdPPL1MLS0bbU3CTpDcacr4KyAKAL8sVi7-M2UVqvtWkEZCJ9q1cgOFwcp0t8ZKOpw9OgVeyo-P8HoDpfeXM_WecqNuHSRBlJGbAIfKErBiAUAKFmdEKyHtuUi-Ni6cEwDgjrSxX3apxG_41POrZjZBuuV6FYBcR1wqnTr8k-_z49Kv8ZGF3yszgcV3IQ4qK3-M_qqypnEai8\",\"e\":\"AQAB\",\"d\":\"BA_s3b-SNNOPqRBH0NSnFftZeRJB6KpR0cSrFSpL-H1ASgZNX2ZLMzKmaDiHe3Hez06apyt9yDVPXIA9kxiYAiXyE_OEEeuEbpf2F-Ct-kqx8r5dASBAiqyGibCdY683Y88W2ZtrmdkW3d131DZ5AN3BC_zn5le_rNM4azTQyxAmdjKnrz0hG2mLp2kjEJhbm4Rb5gZ_R0P2u2oWqmHfgY1pJfLyReHxc3sl8iS8fm8jlFQ7pvlKwAXuo494Ldz4MPvB09nZCegYYsEdEiSkTbssia0F64lusCdHtNaCPsaW3psqPz-mI3QcTdTpgGRFegbL_EHcR2iEFQTXEJi0j8KqfWCsyKY57lJV0Pn6rMTBJ5sF0qSJTnCUZV1BDUN1phhDQoCD0Y44PKdIzsmsgmn1FGjCfixWAMtFSQz8jigyZmsGnmDjKPFUXygL_IYAUqejeObUUe07EYEw4b9a-XgwWe5k1OldLEwOQMji8r7Q38zq6l0plJLdKRJzbF5q7b24TcFrASklca93VkD4hSnLaneeQ_BMVndeJ2f4zPjgFyn70jKXCqralMY1v07I1eSrScRq7it259E2vPas2Y09LeNZxv4ifF6HoD-9eGoUia8NjzKzLj2x3YA39oxRNUidKH3Fk8MCLgAiV2DqVCogFg0EBLEnj7ZjpVjRVCU\",\"p\":\"6xgjjtpZ_ZRkpm45BFaXhN1f6w6-YC_EZkndORGWmYzOitcoJQ64JdEFN-NO_tdmtoNXgV-Fqy_x3jxrXLuHsBv6krxgCfg0Qh9b55K34zikX7AeKSFSrvKcoIXXQVTEQ82gO4TL8T04uWCsoTqN2FNrSENXx6b3MgTaMTWA0JHG7mbfJybcm-3C-qiNKa698dgEpLTgqzDYjn3BoDYD1Ct9Zuy4_nZb8_V_LZxETxwDr7TMA9PKM3I7xqcrH62HVRJoYlrJ7giD9MF0Dw9c0cNcfbcj-gjRonDHekFd8cZUyOM2kCs43uStAWxBf58kUOOptb5czb8vayE9lmCF8w\",\"q\":\"tQ4HyQEsWV0YWBrpZBBHpvlIJQW5hbGM-4zq0DuN5n1T6kYJOjF4zLEnblHUp5skbASaQsHABDQVNDWrCSsYUV_9SvSldjQ7Yp_CbpNOOx4p9D2LYLe1XQVvut8Hloxt4-sqoS0A-alv7FJgWLHrTjozrsnGj7g5N0Q8AFTgB4SHu2jrt-xROg6ZkfFBFOHYPzJERRfm8qYS9sP3-u4aI3KI6y8POG9za1OPWsBkqXmMS4Lwe5QjtTCPeec9Lh_ipQaaxSSf5-jz01NOLTTywkyPNzV5wB13yl39KhKBZFs6wpZERfpnAOH7ROqKq0Q5RIg9qY9rzGFOs4HP4IHt1Q\",\"dp\":\"3rJqFItQjb6BLYrh5fMk6s5Nazv3KOR21jKIJeQ8Vc4lZS31ME1mMSR0HgHsNcnT2XZHcR0MYSI0qsFvLlPScAfA8DkTfL4quqw8AfxgxxRD2QTbPTj8uw7FQeYnBxMGK_hgHaFpE2dcEXa7cKsn7NDwom5we4b1SOOB0PWOxYQh_nliUBMnDWpHtevudJq8AZkQpPlWjbPin_AOd_ZS4CwmSVZa02lJJ6rZQ1pw9sNh1pKcY8-_DcbbSw3V8tcNiI-8Y9b-y8YzQanzh8SUt3upZMkUgmjSNF9DBtNe64VlkTpy2FSpNbNHEz76OKuG2j0e6TOfc6L0hzXgwk9C8w\",\"dq\":\"of7RvGlOUw7Wz04U8TEXyzBT-rwqiJKaQCCPoI0Io-gTAxRzARxup0cCrtSM3wITDor3sy9ELP6k0jgKtoNWmMi4Cy7mNOL7F302LFWks4SDqUK_yGPW5EoO9DbFxVAUqs8pL1ji_H8740i5Z-KZVT8CKyvie4kruGVXAjzuzgsonuh7r-7DppyVj107DAIeyDyjlOaT_xvU7_HbmSsdPAYot7U9exNNRARZyatG5dQZUR7xKMEdSesPFNVviiuBUIKeTDI-2PM35ictVYmAg5SYt58jNl-nZOu_rrssBq0R4DUvFSW8r6-CcOEh_adnTghQk7v9ibqu_jHx20ClmQ\",\"qi\":\"mnQbqLs7dXj9qKHWBMWWfthizpy4YMgpJKwuI1Z5dAbbMIqa--3L3Lx4umCSs6kUPaIVH4_MvehAgcxC1IVilkQe5tpXsC84QAye-XFThsgASNGB7NW1tvnGEoNnUMTd_Ifk4Dr6yCS89tf3eZynDQw1xnk-W2XOXcNTOX2mQYr8v6R2wSL8Vy-CApzQr6vu4pthQBte5aCpYf85YLsNTQrSdxCdj7K3IE0CZKxMdWfgOugGU0dTZJO3U1IPAHgqN5XwNSI1-C6igTqGY7i6SdfG-raBSxrjsLDLWNWS3EpDrWxQQBUP8am4IrSmaKJB-k6Gn0Sde8DMYRTL3uwdAA\"}," +
+                "{\"kty\":\"RSA\",\"kid\":\"r4\",\"use\":\"enc\",\"n\":\"srRMqzPSg5CoMyaY5YErUQBRJkn0QhkzSiIIPA6dow3MnhR2_1S-D4aNHdet29Yc6qs9Qh6HIirMWcp2FPaKfaIZaJ-Q_-9gVyPDWlKHp9jSTeSetDCxm401e8XxNMjluGqb-3uQWE9W0Ka7IlDXXW1KhLYZ75xDaP5Y1c2n84uMRMKwylNCKQv0KlHIRDhsPfHx82khTGUb1XMqom7FWO8Ii4whRr7Glw0JiXj8ANHGozVTP-EVkZqFRJmwLG-ndyvsJOclEwwrXYqklFloU7WUwZQ5M08F-g-6XlSNHtaDcFagUUQKXG8zSb6GqXtEfhrs0mwI1D66b3txAf_76w9phkwlHp0Ab_lLuJLAr0j_ACtXbyxUQvHOV8QXmBuSwl7dVqAXFXGBQNGRtdewjPYgzmS4l_SzjgvC8jRTd-xzSof_gIIbSrKEtMnIoKhMCexyYGXkEzfv7aZH92_ZDGa9Cszlyqd3TJrDjj75zrkztc3coMOgbIVHoet_Ptmx\",\"e\":\"AQAB\",\"d\":\"H4aKLfuu7BHVcmyhNX-zjg8hwcDzK8P5Vd8qF7o2WgEBs3OFyKaA_wksFPMrEyizIj0CSgtLqJ3nPgHnEeyqYt55YAkiUdw_YTAIcwMzNkucUix-SOh8NKZVJJg3ZKn6SK3aBaP3Q3T_qkB3q-aaD7vLlRzw92HYTInuTw2ATwkzvh-gg5jrh4U51ktmKo7PnZ_0oI3P14PQxLeT8mLbQsSse73FUw8txpEAuTVUM6rOQZWTMaY6IV0inIcGWth5ZYWsRnG_0tSyWwdV4L9SoAcGpKbDaZz4aVe9_BauwaBZC02-jeF9-tQXoIp4JehQKJIVwNQDXlwaSNoCEtibCa6ElEHAkTuKeFa9EZQ0_raRZbpxLIayOwGej0xtqrk2Xx1sPHbHCBvoBbU3aA87RiqHfe2GKqQ112HYs2Bli0lYUVD383HW6z52-oD1P_rBSldDi-HD_ALnanV9WIlsDXy35n-O2UrYH8acbgei_acpbqCew_ut_xwL23-O8Chp\",\"p\":\"yYrW8ZH3FxxBoDD9eI3mi02L6MwXNyyptYWHubefzgiAXxjjc9_ZyWFeNPuuhFibWABqU9ZRBOo4rz8tVMt3BCD4uy3Tc-CgqHE_rF3IRCCtpKg4zjDk8zR38z1MgdkFOmptMua4sRyu3zNHUjQaE0TM7oMbmTEZum5_sTXh35nYr93zS6PXEaXat1SQQJCmeY1_O9Oh33mRcqNUQRNNy9m5UrBXPEzzpBvpbpbpJyCFGOXwl620JyMMhz12AAOd\",\"q\":\"4v2yuCdZkdz_z4k3gj5fr9BYCQ3soqi-EGQVWjBBWbnQdRjlVqR2GDptoOu0O5Pfp7KtNY2ZM2R6u5cPp_bpC8lKdXEivIC08STAUxQs_2OGN00_zIc25iruGoErfelWu3lLy5MeIxQyNhplgfLwYEFfM4vU0Aj-56YpgiKG0IL4yJTUTHoKrDnc6EewkOTsaBeyplSM8Bb-8Fiz9rDCw-qAoYyfiurOtRbgqePwE6Mb-qrBf18xWV3H7eMzmWQl\",\"dp\":\"KznD7_vGawZ8bMcVFg4ZLDdtknhzYjoKDAyfl41ykNXx8nN8FRYlt7NSaTqxq2D1sGIma-TDa7JwheWe61jYJeKMdljVyTycOIRRi75xfWsk0vPhexexgxf1wg2box3QqT66PPiPFC16tBRjb5YNIaTX7y_fc3O8eOfKK0_LKhHtD4si604winBwAHH6nl5n1hoq98HkLfH86AFvyKVDQj1oKfv4Oc6nUsNJxZZIW0P2R-jJOT7gLKSvwzHDZS1h\",\"dq\":\"B0GS5_4iB96nssuxIZG631Tqq4dtbBm20bFRWWu3exXMiyG7mxRwzf94J6_BODJW8PZuQQsAvbrVjY-bqYPkGUNbBPwT3zDCF_9TwpQfiB53WOc4ReKAp8TxjZlZeZHu-tk6ygwu53Iq1L3tRsUsV_dfArfSmr_e3iraotVVt-6n40mWq8cu9ih3XlmEVG1s_TrctCJ5yucBSU-cmSM3ZqnlaMSlCPzOlM1hayzlLMuHBnFU9Cxn2HJ-BKXBrYKd\",\"qi\":\"vp98xF5g3Qrl7N8xrMxcv3dlzc604uriOJWlU1i0cnitx4A41sy_0gGUU7CUK-E-3zsM0jyKbhdmxAS7RKjKJx4bRLd-sSrhyX7CVuQfnhf4FPhrvDWhrpP_gF00sZp0YlzJCK2RTAYVJu-l0h-Ha-aeqM-i38sB5Mil2G3pEfesTnU8P0QkpDiKyIPenSVyndBgCyEwM7ohg0R4J6v7pr91CKe5VU5pBVCUQ-Cc9qKz_5eQYrZn9KdI4uuJQgG6\"}," +
+                "{\"kty\":\"EC\",\"kid\":\"e1\",\"use\":\"enc\",\"x\":\"zw4_6TARtwAsHFDw4Q1gr65t6BMl6lXOmmOMA3R0q58\",\"y\":\"O0Gb45b83A8FRe-DH_xJ4H0dsaQVskZMT_RBIKaSGOc\",\"crv\":\"P-256\",\"d\":\"wS8p82eHEJ6909QDq2duIcVNCtUt15BSkGGepzDnJQ8\"}," +
+                "{\"kty\":\"EC\",\"kid\":\"e2\",\"use\":\"enc\",\"x\":\"A47oP1eLgWo7NsiKGV2Q983D3oNxLnRDlgtEi7HCtSI\",\"y\":\"4CjFGXRHDmm3g_cSB2YZPYsnxorc4tAEJRD35wBu0ys\",\"crv\":\"P-256\",\"d\":\"FfbZoojxU87u-lLtCUMHRWwFU2w1eB6yEEuJmm-Rhno\"}" +
+                "]}");
+
+//        JsonWebKey k = jsonWebKeySet.findJsonWebKey("e2", null, null, null);
+//
+//        JsonWebEncryption jwe = new JsonWebEncryption();
+//        jwe.setPayload("{\"iss\":\"e2\"}");
+//        jwe.setKey(k.getKey());
+//        jwe.setAlgorithmHeaderValue(KeyManagementAlgorithmIdentifiers.ECDH_ES);
+//        jwe.setEncryptionMethodHeaderParameter(ContentEncryptionAlgorithmIdentifiers.AES_128_GCM);
+//        String compactSerialization = jwe.getCompactSerialization();
+//
+//        System.out.println(compactSerialization);
+
+        List<JsonWebKey> jsonWebKeys = jsonWebKeySet.getJsonWebKeys();
+        Collections.shuffle(jsonWebKeys);
+
+        String jwer1 = "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.KCBLPXZnT5aaFM6jnB7QhFhZ3dkD4Ky7OF8SWlHbKzWx4kuGtOvre0MJBnfMuwEND1a67QdNO1rag1_P78fEcz5Zs71aYDnwNWAagQhsWXx32-1gtmQR90etJkbT8qDA98MIB_WdBeJLwUD8CIOz1BrMcWHdX9NZcVxi1NZW4boi9qw_Dtst9r806FMnSR0-wmp2wTzYsR5Lmalg3WA-QwM-N2pMXi3J_C2QavM7ml1Lg1utjis_YrsvAI19iWPLRcYhH0dIaf2uRCAzhzHy8g4kQkbp70LNd9XXCNq-3lhA-1VqnsLi0V2LV3H0olR06jre9VOHC0fgzeUCTA6UrA.wvCoV_JQhm9eEsco.04sa9TFzOz0lfaWR.h8spUAPHrZ0EEQr5xIJTjg";
+        String jwer2 = "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.rFG7gYCkOAxjaRIFoz_DUy0f83G2UG2V9DSTRcg-4e05EPSiDLE9KCWsWZU43cwl2JwQP1zUTyU-K3MW6u7lpFXGIX-9AqFqPFTfGUYDymnM7JJ9Bjyl42dCaNuOx-0UhodIUbxMUFsSDQ1LvWIDuJKCQsK7mXw0Lrbj-Wa_xK8CpsD9Z25BulwkD5srfvJ0zRvhlX5SA3enGlYWp8hPxDcyXfP2IJK_JBFzefK76soDQ-IcpOTE6BbdATHYL5aQUKM1rKdShZL1M7VISI_lUFx1FC8BIKf_k8YTYGNIE41_sCnNXhrKzs4g45B_sYpNnX71Rs3g6WOXKtjW83Pf_Q.mVb0fTuF6u72mYGS.YwwtHaLPzxnU3krt.aEXq4r4JaJhZxvxRX16ZPw";
+        String jwer3 = "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.He_InN2BUqvy9sfq_uwOnXTrEdFcII-eJiwNIE9ZH806VWK8WvxBLYczgR4nfB6E603Wk7pgMM85ys2ONu-GfEhprkC2Kmogcs18V2k7rXx6Vs7qMYkC-KCesa-qxOkh2Q5p_JbXcXoMvhpRtcPxHnIPSc8A8thlV0nUPvCSFJF9oqNlb3LnYiPFSj7UN0NbrrRP1l_UJs51MGRsAsz6EvpXhZQe_lDZ2RvKzXdJjV32-1amYbZKINFnneyomRLv4koc5wHdrl_tra95W1GnnzccQ8JaHUDyXAp7wKWcG2m0gXcbvVvYaHtXYlKujrYrcX31LXla4gFIJ1dOvqHn7562fUWvyBiBe-umpgwXjQq8pt6flHlKedYfefwAjg96z1_vIGD995Z2vZ2DjQmsBFGa5P115IeO2czGRicmo3x9Oy_KnJ3y2Xl7Dd_ItNzKXuDTRxYqU3bghQ0G6toouddpMvdwYhUqZ4eRkgqiMrNa2tjA-Zss8FaBoxfBTWR3TMOMFoydPPnlyJrla8MunL5GAyALxAYKF2AOhEXX_isPtORjLyIiUaril0SpUYGpwsftb2enjJqxFJRHmfCFw7_0fmwD8TLfr00DW6r8Jgf4nZgeA90V6IzJZq_1hvj1eoTlNSBYbN6i3Ur9l7XCGBiQDgFzshBW7jm5NlUCrpU.A-j_xMjFn2cA4K9-.wpw6nZ7unz9AgSY3.6OjRwTShxXHmdby5aAUYAQ";
+        String jwer4 = "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.awMpGgt-UTQYOQBO4Z-sABTVhrSr70xjotF0FMXWFqUB4iyoihdLRBTnrpjTb6o-orOqA6EMsv6oDZZelSn3J5Ul-cJSPibXuehlX9VQkZv4NDhP38sUeuXNp0IDtNcJeX2tFI2t6W2uFrCYwIkvh8f8bKHR_yUZslFBWAXRwLX9H2PjyQLXhir3hM1SAOKrQQVjaoPOum1n-3F6p_fh8gZYaxVJiJ2Yq9kdqVwY1wjsEq5sq8JN3j8szfE1GBVYHQhdn2I96bpX9OI97ma-XDIZwmQRgHT1mMByhbTG1SzQiIOc4CXGp5b5zER8j55MVZYB0L3iPYVEELY5YjWULc8XTUeSkejvH3ENuckqBoMijx3vb3NIXUFvY1IW6l0DeCxEbv87ead-qSRoCNWKsZKtNX457jhtl9xXO0lrjT5kB_D9z_0SbT2X7CTIZ4vMGBbzsII-Ip_cWwl8xYXxwy9OGVsiRt1F0q1JgtNS35lNP9hZvDJksWPo59ebqXEw.ocPwwRIpGa8R3Vov.-XXqFCYM6zkOTl3j.hOTzs7STvZrH3Agtm4DoNg";
+        String jwee1 = "eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImVuYyI6IkExMjhHQ00iLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiNGUxaFNtaG1wUkFTQWU0SGZvNnRWbFlUbmhIazhXU3RWN3JhdXowSERmdyIsInkiOiJqY2xlM1I3UW9heU1STEdkU3RVRnRXa19tbEFRcDdnUjRzMmlUSW9oUFk0IiwiY3J2IjoiUC0yNTYifX0.sYGf24IFPG3CpVZNAK6ApOKu6-xO7R7y.sK0Sh40MFYIRPF0j.iZRU7bUnWlMW7XT_.gDIU8HHyNxf7HORt6b8NfQ";
+        String jwee2 = "eyJhbGciOiJFQ0RILUVTIiwiZW5jIjoiQTEyOEdDTSIsImVwayI6eyJrdHkiOiJFQyIsIngiOiJCM1FfY2xpV2FDMXlJVy0zZmZkY3hUNUx4eDlwMEtLWjIzOFF2aDRaM0JVIiwieSI6InVwdTRqMkJrMHE4a09JSEVGdGxLNF9ZZE9LRHBNbHNJNlBiUTZpM0dfOGciLCJjcnYiOiJQLTI1NiJ9fQ..UThHTj4NK_nuFTlN.3jZICW52F3hFd_jg.RJxLHhVO_-EJYYWrui3CWw";
+
+        final ArrayList<String> jwes = new ArrayList<>(Arrays.asList(jwee1, jwee2, jwer1, jwer2, jwer3, jwer4));
+        Collections.shuffle(jwes);
+
+        final JwksDecryptionKeyResolver decryptionKeyResolver = new JwksDecryptionKeyResolver(jsonWebKeys);
+        decryptionKeyResolver.setDisambiguateWithAttemptDecrypt(true);
+
+        JceProviderTestSupport jceProviderTestSupport = new JceProviderTestSupport();
+        jceProviderTestSupport.setEncryptionAlgsNeeded(ContentEncryptionAlgorithmIdentifiers.AES_128_GCM);
+        jceProviderTestSupport.runWithBouncyCastleProviderIfNeeded(new JceProviderTestSupport.RunnableTest()
+        {
+            @Override
+            public void runTest() throws Exception
+            {
+                for (String jwe : jwes)
+                {
+                    JwtConsumer jwtConsumer = new JwtConsumerBuilder()
+                            .setSkipAllValidators()
+                            .setDisableRequireSignature()
+                            .setDecryptionKeyResolver(decryptionKeyResolver)
+                            .build();
+
+                    JwtClaims jwtClaims = jwtConsumer.processToClaims(jwe);
+                    assertThat(jwtClaims.getIssuer(), is(notNullValue()));
+                }
+
+                String jwer4bad = "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.Ac5pGgt-UTQYOQBO4Z-sABTVhrSr70xjotF0FMXWFqUB4iyoihdLRBTnrpjTb6o-orOqA6EMsv6oDZZelSn3J5Ul-cJSPibXuehlX9VQkZv4NDhP38sUeuXNp0IDtNcJeX2tFI2t6W2uFrCYwIkvh8f8bKHR_yUZslFBWAXRwLX9H2PjyQLXhir3hM1SAOKrQQVjaoPOum1n-3F6p_fh8gZYaxVJiJ2Yq9kdqVwY1wjsEq5sq8JN3j8szfE1GBVYHQhdn2I96bpX9OI97ma-XDIZwmQRgHT1mMByhbTG1SzQiIOc4CXGp5b5zER8j55MVZYB0L3iPYVEELY5YjWULc8XTUeSkejvH3ENuckqBoMijx3vb3N3XUFvY1IW6l0DecXEbv87ead-qSRoCNWKsZKtNX457jhtl9xXO0lrjT5kB_D9z_0SbT2X7ffsZ4vMGBbzsII-Ip_cWwl8xYXxwy9OGVsiRt1F0q1JgtNS35lNP9hZvDJksWPo77ebqXEw.ocPwwRIpGacR3VO1.-XXqFCYM6zkOTl3j.hOTzs7STvZrH3Agtm4DoNg";
+                try
+                {
+                    JwtConsumer jwtConsumer = new JwtConsumerBuilder()
+                            .setSkipAllValidators()
+                            .setDisableRequireSignature()
+                            .setDecryptionKeyResolver(decryptionKeyResolver)
+                            .build();
+
+                    JwtClaims claims = jwtConsumer.processToClaims(jwer4bad);
+                    fail("shouldn't have processed/validated but got " + claims);
+                }
+                catch (InvalidJwtException e)
+                {
+                    log.debug("this was expected and is okay: {}", e.toString());
+                }
+            }
+        });
+    }
+
+    @Test
+    public void simpleSymmetricDecryptionKeysWithDisambiguate() throws Exception
+    {
+        List<JsonWebKey> keys = new ArrayList<>();
+        OctetSequenceJsonWebKey jwk = OctJwkGenerator.generateJwk(256);
+        jwk.setKeyId("1");
+        keys.add(jwk);
+        jwk = OctJwkGenerator.generateJwk(256);
+        jwk.setKeyId("2");
+        keys.add(jwk);
+        jwk = OctJwkGenerator.generateJwk(256);
+        jwk.setKeyId("3");
+        keys.add(jwk);
+        jwk = OctJwkGenerator.generateJwk(256);
+        jwk.setKeyId("4");
+        keys.add(jwk);
+        jwk = OctJwkGenerator.generateJwk(256);
+        jwk.setKeyId("5");
+        keys.add(jwk);
+        jwk = OctJwkGenerator.generateJwk(256);
+        jwk.setKeyId("6");
+        keys.add(jwk);
+
+        List<String> jwes = new ArrayList<>();
+
+        for (JsonWebKey jsonWebKey : keys)
+        {
+            String jwe = makeSimpleSymmetricJwe(jsonWebKey);
+            jwes.add(jwe);
+        }
+
+        JwksDecryptionKeyResolver decryptionKeyResolver = new JwksDecryptionKeyResolver(keys);
+        decryptionKeyResolver.setDisambiguateWithAttemptDecrypt(true);
+
+        for (String jwe : jwes)
+        {
+            JwtConsumer jwtConsumer = new JwtConsumerBuilder()
+                    .setSkipAllValidators()
+                    .setDisableRequireSignature()
+                    .setDecryptionKeyResolver(decryptionKeyResolver)
+                    .build();
+
+            JwtClaims jwtClaims = jwtConsumer.processToClaims(jwe);
+            assertThat(jwtClaims.getIssuer(), is(notNullValue()));
+        }
+
+        jwk = OctJwkGenerator.generateJwk(256);
+        jwk.setKeyId("nope");
+        String jwe = makeSimpleSymmetricJwe(jwk);
+
+
+        try
+        {
+            JwtConsumer jwtConsumer = new JwtConsumerBuilder()
+                    .setSkipAllValidators()
+                    .setDisableRequireSignature()
+                    .setDecryptionKeyResolver(decryptionKeyResolver)
+                    .build();
+
+            JwtClaims claims = jwtConsumer.processToClaims(jwe);
+            fail("shouldn't have processed/validated but got " + claims);
+        }
+        catch (InvalidJwtException e)
+        {
+            log.debug("this was expected and is okay: {}", e.toString());
+        }
+
+    }
+
+    private String makeSimpleSymmetricJwe(JsonWebKey jsonWebKey) throws JoseException
+    {
+        JsonWebEncryption jwe = new JsonWebEncryption();
+        jwe.setAlgorithmHeaderValue(KeyManagementAlgorithmIdentifiers.DIRECT);
+        jwe.setEncryptionMethodHeaderParameter(ContentEncryptionAlgorithmIdentifiers.AES_128_CBC_HMAC_SHA_256);
+        jwe.setPayload("{\"iss\":\"made w/ kid "+ jsonWebKey.getKeyId()+"\"}");
+        jwe.setKey(jsonWebKey.getKey());
+        return jwe.getCompactSerialization();
+    }
+
 }
diff --git a/src/test/java/org/jose4j/jwt/consumer/JwtConsumerTest.java b/src/test/java/org/jose4j/jwt/consumer/JwtConsumerTest.java
index 5c3f949..3065ec0 100644
--- a/src/test/java/org/jose4j/jwt/consumer/JwtConsumerTest.java
+++ b/src/test/java/org/jose4j/jwt/consumer/JwtConsumerTest.java
@@ -318,17 +318,6 @@ public class JwtConsumerTest
                 .setExpectedIssuer("joe");
         jwtConsumer = builder.build();
         SimpleJwtConsumerTestHelp.expectProcessingFailure(jwt, jwtContext,  jwtConsumer);
-
-        builder = new JwtConsumerBuilder()
-                .setDecryptionKey(ExampleRsaKeyFromJws.PRIVATE_KEY)
-                .setEnableRequireEncryption()
-                .setVerificationKey(verificationKey)
-                .setRequireExpirationTime()
-                .setEvaluationTime(NumericDate.fromSeconds(1300819380))
-                .setAllowedClockSkewInSeconds(30)
-                .setExpectedIssuer("joe");
-        jwtConsumer = builder.build();
-        SimpleJwtConsumerTestHelp.expectProcessingFailure(jwt, jwtContext,  jwtConsumer);  // already decrypted but different key so seems good to fail
     }
 
     @Test
diff --git a/src/test/java/org/jose4j/keys/resolvers/EmbeddedJwkVerificationKeyResolverTest.java b/src/test/java/org/jose4j/keys/resolvers/EmbeddedJwkVerificationKeyResolverTest.java
index 1d2a03e..72772b1 100644
--- a/src/test/java/org/jose4j/keys/resolvers/EmbeddedJwkVerificationKeyResolverTest.java
+++ b/src/test/java/org/jose4j/keys/resolvers/EmbeddedJwkVerificationKeyResolverTest.java
@@ -110,4 +110,25 @@ public class EmbeddedJwkVerificationKeyResolverTest
 
 
     }
+
+    @Test
+    public void testMakeSureJwkHeaderWithPrivateKeyIsRejected() throws Exception
+    {
+        String jwt = "eyJhbGciOiJFUzI1NiIsInR5cCI6ImRwb3Arand0IiwiandrIjp7Imt0eSI6IkVDIiwieCI6Ijc2blk4UGtTVkE4MG" +
+                "lPUHEzVUVHbm9jdU9HaFFqR09rY1BwYnlXcHNXbWciLCJ5IjoiMDBMWkIySWNPeEVya05ad2NRWF9kbXVkay1hdE9STUtqR" +
+                "EJUc1VlTXZvVSIsImNydiI6IlAtMjU2IiwiZCI6IklJYlhwVWJJSGVtT0FyZWVRX0xNMmFrcTd5NjZEY1lsdXZneWRPcml0" +
+                "SlUifX0.eyJqdGkiOiJiYzc4OSIsImh0bSI6IkdFVCIsImh0dSI6Imh0dHBzOi8vYXBpLmV4YW1wbGUuY29tIiwiaWF0Ijo" +
+                "xNjQ3OTU5MTMyfQ.-GKT4h58oZzS4LGk8b44Dh4GoJ9Y2extHUOr_LzbFIibO_XXfanPZ8ePZkXd8s7cuQyFKagePUVCdu1" +
+                "T2UKbTQ";
+
+        EmbeddedJwkVerificationKeyResolver embeddedJwkResolver = new EmbeddedJwkVerificationKeyResolver();
+        JwtConsumer jwtConsumer = new JwtConsumerBuilder()
+                .setVerificationKeyResolver(embeddedJwkResolver)
+                .setEvaluationTime(NumericDate.fromSeconds(1647959133))
+                .setExpectedType(true, "dpop+jwt")
+                .setRequireIssuedAt()
+                .setIssuedAtRestrictions(5, 30)
+                .build();
+        SimpleJwtConsumerTestHelp.expectProcessingFailure(jwt, jwtConsumer);
+    }
 }
\ No newline at end of file

Debdiff

[The following lists of changes regard files as different if they have different names, permissions or owners.]

Files in second set of .debs but not in first

-rw-r--r--  root/root   /usr/share/maven-repo/org/bitbucket/b_c/jose4j/0.7.12/jose4j-0.7.12.pom
lrwxrwxrwx  root/root   /usr/share/java/jose4j-0.7.12.jar -> jose4j.jar
lrwxrwxrwx  root/root   /usr/share/maven-repo/org/bitbucket/b_c/jose4j/0.7.12/jose4j-0.7.12.jar -> ../../../../../../java/jose4j.jar

Files in first set of .debs but not in second

-rw-r--r--  root/root   /usr/share/maven-repo/org/bitbucket/b_c/jose4j/0.7.7/jose4j-0.7.7.pom
lrwxrwxrwx  root/root   /usr/share/java/jose4j-0.7.7.jar -> jose4j.jar
lrwxrwxrwx  root/root   /usr/share/maven-repo/org/bitbucket/b_c/jose4j/0.7.7/jose4j-0.7.7.jar -> ../../../../../../java/jose4j.jar

No differences were encountered in the control files

More details

Full run details