diff --git a/README.adoc b/README.adoc index d0d1c47e3..d9b4c91b6 100644 --- a/README.adoc +++ b/README.adoc @@ -738,7 +738,7 @@ import java.security.Key; // We need a signing key, so we'll create one just for this example. Usually // the key would be read from your application configuration instead. -SecretKey key = Jwts.SIG.HS256.key().build(); +SecretKey key = Jws.alg.HS256.key().build(); String jws = Jwts.builder().subject("Joe").signWith(key).compact(); ---- @@ -1611,7 +1611,7 @@ key algorithms: ^*2*.{sp}{fn-require-java15-plus}^ -These are all represented as constants in the `io.jsonwebtoken.Jwts.SIG` registry class. +These are all represented as constants in the `io.jsonwebtoken.Jws.alg` registry class. ++++++++++++ @@ -1705,7 +1705,7 @@ algorithm's `key()` builder method: [,java] ---- -SecretKey key = Jwts.SIG.HS256.key().build(); //or HS384.key() or HS512.key() +SecretKey key = Jws.alg.HS256.key().build(); //or HS384.key() or HS512.key() ---- Under the hood, JJWT uses the JCA default provider's `KeyGenerator` to create a secure-random key with the correct @@ -1716,7 +1716,7 @@ as builder arguments. For example: [,java] ---- -SecretKey key = Jwts.SIG.HS256.key().provider(aProvider).random(aSecureRandom).build(); +SecretKey key = Jws.alg.HS256.key().provider(aProvider).random(aSecureRandom).build(); ---- If you need to save this new `SecretKey`, you can Base64 (or Base64URL) encode it: @@ -1739,7 +1739,7 @@ algorithms, use an algorithm's respective `keyPair()` builder method: [,java] ---- -KeyPair keyPair = Jwts.SIG.RS256.keyPair().build(); //or RS384, RS512, PS256, etc... +KeyPair keyPair = Jws.alg.RS256.keyPair().build(); //or RS384, RS512, PS256, etc... ---- Once you've generated a `KeyPair`, you can use the private key (`keyPair.getPrivate()`) to create a JWS and the @@ -1874,7 +1874,7 @@ that accepts the `SignatureAlgorithm` as an additional argument: [,java] ---- - .signWith(privateKey, Jwts.SIG.RS512) // <--- + .signWith(privateKey, Jws.alg.RS512) // <--- .compact(); ---- @@ -2062,7 +2062,7 @@ We need to do three things during creation: [,java] ---- // create a test key for this example: -SecretKey testKey = Jwts.SIG.HS512.key().build(); +SecretKey testKey = Jws.alg.HS512.key().build(); String message = "Hello World. It's a Beautiful Day!"; byte[] content = message.getBytes(StandardCharsets.UTF_8); @@ -2105,7 +2105,7 @@ period (`.`) characters_*. [,java] ---- // create a test key for this example: -SecretKey testKey = Jwts.SIG.HS512.key().build(); +SecretKey testKey = Jws.alg.HS512.key().build(); String claimsString = "{\"sub\":\"joe\",\"iss\":\"me\"}"; @@ -2225,7 +2225,7 @@ The JWT specification defines 6 standard Authenticated Encryption algorithms use | AES GCM using 256-bit key |=== -These are all represented as constants in the `io.jsonwebtoken.Jwts.ENC` registry singleton as +These are all represented as constants in the `io.jsonwebtoken.Jwe.alg` registry singleton as implementations of the `io.jsonwebtoken.security.AeadAlgorithm` interface. As shown in the table above, each algorithm requires a key of sufficient length. The JWT specification @@ -2370,7 +2370,7 @@ Content Encryption Key (CEK): | PBES2 with HMAC SHA-512 and "A256KW" wrapping |=== -These are all represented as constants in the `io.jsonwebtoken.Jwts.KEY` registry singleton as +These are all represented as constants in the `io.jsonwebtoken.Jwe.enc` registry singleton as implementations of the `io.jsonwebtoken.security.KeyAlgorithm` interface. But 17 algorithms are a lot to choose from. When would you use them? The sections below describe when you might @@ -3740,7 +3740,7 @@ Example: [,java] ---- // Create a test key suitable for the desired HMAC-SHA algorithm: -MacAlgorithm alg = Jwts.SIG.HS512; //or HS384 or HS256 +MacAlgorithm alg = Jws.alg.HS512; //or HS384 or HS256 SecretKey key = alg.key().build(); String message = "Hello World!"; @@ -3769,7 +3769,7 @@ public key: [,java] ---- // Create a test key suitable for the desired RSA signature algorithm: -SignatureAlgorithm alg = Jwts.SIG.RS512; //or PS512, RS256, etc... +SignatureAlgorithm alg = Jws.alg.RS512; //or PS512, RS256, etc... KeyPair pair = alg.keyPair().build(); // Bob creates the compact JWS with his RSA private key: @@ -3802,7 +3802,7 @@ public key: [,java] ---- // Create a test key suitable for the desired ECDSA signature algorithm: -SignatureAlgorithm alg = Jwts.SIG.ES512; //or ES256 or ES384 +SignatureAlgorithm alg = Jws.alg.ES512; //or ES256 or ES384 KeyPair pair = alg.keyPair().build(); // Bob creates the compact JWS with his EC private key: @@ -3854,7 +3854,7 @@ KeyPair pair = curve.keyPair().build(); // Bob creates the compact JWS with his Edwards Curve private key: String jws = Jwts.builder().subject("Alice") - .signWith(pair.getPrivate(), Jwts.SIG.EdDSA) // <-- Bob's Edwards Curve private key w/ EdDSA + .signWith(pair.getPrivate(), Jws.alg.EdDSA) // <-- Bob's Edwards Curve private key w/ EdDSA .compact(); // Alice receives and verifies the compact JWS came from Bob: @@ -3891,7 +3891,7 @@ Example: ---- // Create a test key suitable for the desired payload encryption algorithm: // (A*GCM algorithms are recommended, but require JDK >= 8 or BouncyCastle) -AeadAlgorithm enc = Jwts.ENC.A256GCM; //or A128GCM, A192GCM, A256CBC-HS512, etc... +AeadAlgorithm enc = Jwe.alg.A256GCM; //or A128GCM, A192GCM, A256CBC-HS512, etc... SecretKey key = enc.key().build(); String message = "Live long and prosper."; @@ -3922,12 +3922,12 @@ decrypt the JWT using her RSA private key: [,java] ---- // Create a test KeyPair suitable for the desired RSA key algorithm: -KeyPair pair = Jwts.SIG.RS512.keyPair().build(); +KeyPair pair = Jws.alg.RS512.keyPair().build(); // Choose the key algorithm used encrypt the payload key: KeyAlgorithm alg = Jwts.KEY.RSA_OAEP_256; //or RSA_OAEP or RSA1_5 // Choose the Encryption Algorithm to encrypt the payload: -AeadAlgorithm enc = Jwts.ENC.A256GCM; //or A192GCM, A128GCM, A256CBC-HS512, etc... +AeadAlgorithm enc = Jwe.alg.A256GCM; //or A192GCM, A128GCM, A256CBC-HS512, etc... // Bob creates the compact JWE with Alice's RSA public key so only she may read it: String jwe = Jwts.builder().audience().add("Alice").and() @@ -3964,7 +3964,7 @@ SecretKeyAlgorithm alg = Jwts.KEY.A256GCMKW; //or A192GCMKW, A128GCMKW, A256KW, SecretKey key = alg.key().build(); // Chooose the Encryption Algorithm used to encrypt the payload: -AeadAlgorithm enc = Jwts.ENC.A256GCM; //or A192GCM, A128GCM, A256CBC-HS512, etc... +AeadAlgorithm enc = Jwe.alg.A256GCM; //or A192GCM, A128GCM, A256CBC-HS512, etc... // Create the compact JWE: String jwe = Jwts.builder().issuer("me").encryptWith(key, alg, enc).compact(); @@ -3994,12 +3994,12 @@ Alice can then decrypt the JWT using her Elliptic Curve private key: [,java] ---- // Create a test KeyPair suitable for the desired EC key algorithm: -KeyPair pair = Jwts.SIG.ES512.keyPair().build(); +KeyPair pair = Jws.alg.ES512.keyPair().build(); // Choose the key algorithm used encrypt the payload key: KeyAlgorithm alg = Jwts.KEY.ECDH_ES_A256KW; //ECDH_ES_A192KW, etc... // Choose the Encryption Algorithm to encrypt the payload: -AeadAlgorithm enc = Jwts.ENC.A256GCM; //or A192GCM, A128GCM, A256CBC-HS512, etc... +AeadAlgorithm enc = Jwe.alg.A256GCM; //or A192GCM, A128GCM, A256CBC-HS512, etc... // Bob creates the compact JWE with Alice's EC public key so only she may read it: String jwe = Jwts.builder().audience().add("Alice").and() @@ -4046,7 +4046,7 @@ KeyAlgorithm alg = Jwts.KEY.PBES2_HS512_A256KW; //or PBES2_H //int pbkdf2Iterations = 120000; //for HS512. Needs to be much higher for smaller hash algs. // Choose the Encryption Algorithm used to encrypt the payload: -AeadAlgorithm enc = Jwts.ENC.A256GCM; //or A192GCM, A128GCM, A256CBC-HS512, etc... +AeadAlgorithm enc = Jwe.alg.A256GCM; //or A192GCM, A128GCM, A256CBC-HS512, etc... // Create the compact JWE: String jwe = Jwts.builder().issuer("me") @@ -4070,7 +4070,7 @@ Example creating and parsing a secret JWK: [,java] ---- -SecretKey key = Jwts.SIG.HS512.key().build(); // or HS384 or HS256 +SecretKey key = Jws.alg.HS512.key().build(); // or HS384 or HS256 SecretJwk jwk = Jwks.builder().key(key).idFromThumbprint().build(); assert jwk.getId().equals(jwk.thumbprint().toString()); @@ -4092,7 +4092,7 @@ Example creating and parsing an RSA Public JWK: [,java] ---- -RSAPublicKey key = (RSAPublicKey)Jwts.SIG.RS512.keyPair().build().getPublic(); +RSAPublicKey key = (RSAPublicKey)Jws.alg.RS512.keyPair().build().getPublic(); RsaPublicJwk jwk = Jwks.builder().key(key).idFromThumbprint().build(); assert jwk.getId().equals(jwk.thumbprint().toString()); @@ -4114,7 +4114,7 @@ Example creating and parsing an RSA Private JWK: [,java] ---- -KeyPair pair = Jwts.SIG.RS512.keyPair().build(); +KeyPair pair = Jws.alg.RS512.keyPair().build(); RSAPublicKey pubKey = (RSAPublicKey) pair.getPublic(); RSAPrivateKey privKey = (RSAPrivateKey) pair.getPrivate(); @@ -4142,7 +4142,7 @@ Example creating and parsing an Elliptic Curve Public JWK: [,java] ---- -ECPublicKey key = (ECPublicKey) Jwts.SIG.ES512.keyPair().build().getPublic(); +ECPublicKey key = (ECPublicKey) Jws.alg.ES512.keyPair().build().getPublic(); EcPublicJwk jwk = Jwks.builder().key(key).idFromThumbprint().build(); assert jwk.getId().equals(jwk.thumbprint().toString()); @@ -4164,7 +4164,7 @@ Example creating and parsing an Elliptic Curve Private JWK: [,java] ---- -KeyPair pair = Jwts.SIG.ES512.keyPair().build(); +KeyPair pair = Jws.alg.ES512.keyPair().build(); ECPublicKey pubKey = (ECPublicKey) pair.getPublic(); ECPrivateKey privKey = (ECPrivateKey) pair.getPrivate(); diff --git a/api/src/main/java/io/jsonwebtoken/Header.java b/api/src/main/java/io/jsonwebtoken/Header.java index f6dd1f9db..3242869ff 100644 --- a/api/src/main/java/io/jsonwebtoken/Header.java +++ b/api/src/main/java/io/jsonwebtoken/Header.java @@ -130,14 +130,14 @@ public interface Header extends Map { *
    *
  • If the JWT is a Signed JWT (a JWS), the * alg (Algorithm) header parameter identifies the cryptographic algorithm used to secure the - * JWS. Consider using {@link Jwts.SIG}.{@link io.jsonwebtoken.lang.Registry#get(Object) get(id)} + * JWS. Consider using {@link Jws.alg}.{@link io.jsonwebtoken.lang.Registry#get(Object) get(id)} * to convert this string value to a type-safe {@code SecureDigestAlgorithm} instance.
  • *
  • If the JWT is an Encrypted JWT (a JWE), the * alg (Algorithm) header parameter * identifies the cryptographic key management algorithm used to encrypt or determine the value of the Content * Encryption Key (CEK). The encrypted content is not usable if the alg value does not represent a * supported algorithm, or if the recipient does not have a key that can be used with that algorithm. Consider - * using {@link Jwts.KEY}.{@link io.jsonwebtoken.lang.Registry#get(Object) get(id)} to convert this string value + * using {@link Jwe.enc}.{@link io.jsonwebtoken.lang.Registry#get(Object) get(id)} to convert this string value * to a type-safe {@link io.jsonwebtoken.security.KeyAlgorithm KeyAlgorithm} instance.
  • *
* diff --git a/api/src/main/java/io/jsonwebtoken/Jwe.java b/api/src/main/java/io/jsonwebtoken/Jwe.java index 885ddae36..9d833db19 100644 --- a/api/src/main/java/io/jsonwebtoken/Jwe.java +++ b/api/src/main/java/io/jsonwebtoken/Jwe.java @@ -15,6 +15,17 @@ */ package io.jsonwebtoken; +import io.jsonwebtoken.lang.Classes; +import io.jsonwebtoken.lang.Registry; +import io.jsonwebtoken.security.AeadAlgorithm; +import io.jsonwebtoken.security.KeyAlgorithm; +import io.jsonwebtoken.security.Password; +import io.jsonwebtoken.security.SecretKeyAlgorithm; + +import javax.crypto.SecretKey; +import java.security.PrivateKey; +import java.security.PublicKey; + /** * An encrypted JWT, called a "JWE", per the * JWE (RFC 7516) Specification. @@ -24,6 +35,713 @@ */ public interface Jwe extends ProtectedJwt { + /** + * Constants for all standard JWA + * Cryptographic Algorithms for Content + * Encryption defined in the JSON + * Web Signature and Encryption Algorithms Registry. Each standard algorithm is available as a + * ({@code public static final}) constant for direct type-safe reference in application code. For example: + *
+     * Jwts.builder()
+     *    // ... etc ...
+     *    .encryptWith(aKey, Jwe.alg.A256GCM) // or A128GCM, A192GCM, etc...
+     *    .build();
+ *

They are also available together as a {@link Registry} instance via the {@link #registry()} method.

+ * + * @see #registry() + * @since JJWT_RELEASE_VERSION + */ + final class alg { + + private static final String IMPL_CLASSNAME = "io.jsonwebtoken.impl.security.StandardEncryptionAlgorithms"; + private static final Registry REGISTRY = Classes.newInstance(IMPL_CLASSNAME); + + /** + * Returns all standard JWA Cryptographic + * Algorithms for Content Encryption defined in the + * JSON Web Signature and Encryption + * Algorithms Registry. + * + * @return all standard JWA content encryption algorithms. + */ + public static Registry registry() { + return REGISTRY; + } + + // prevent instantiation + private alg() { + } + + /** + * {@code AES_128_CBC_HMAC_SHA_256} authenticated encryption algorithm as defined by + * RFC 7518, Section 5.2.3. This algorithm + * requires a 256-bit (32 byte) key. + */ + public static final AeadAlgorithm A128CBC_HS256 = registry().forKey("A128CBC-HS256"); + + /** + * {@code AES_192_CBC_HMAC_SHA_384} authenticated encryption algorithm, as defined by + * RFC 7518, Section 5.2.4. This algorithm + * requires a 384-bit (48 byte) key. + */ + public static final AeadAlgorithm A192CBC_HS384 = registry().forKey("A192CBC-HS384"); + + /** + * {@code AES_256_CBC_HMAC_SHA_512} authenticated encryption algorithm, as defined by + * RFC 7518, Section 5.2.5. This algorithm + * requires a 512-bit (64 byte) key. + */ + public static final AeadAlgorithm A256CBC_HS512 = registry().forKey("A256CBC-HS512"); + + /** + * "AES GCM using 128-bit key" as defined by + * RFC 7518, Section 5.3. This + * algorithm requires a 128-bit (16 byte) key. + */ + public static final AeadAlgorithm A128GCM = registry().forKey("A128GCM"); + + /** + * "AES GCM using 192-bit key" as defined by + * RFC 7518, Section 5.3. This + * algorithm requires a 192-bit (24 byte) key. + */ + public static final AeadAlgorithm A192GCM = registry().forKey("A192GCM"); + + /** + * "AES GCM using 256-bit key" as defined by + * RFC 7518, Section 5.3. This + * algorithm requires a 256-bit (32 byte) key. + */ + public static final AeadAlgorithm A256GCM = registry().forKey("A256GCM"); + } + + /** + * Constants for all standard JWA (RFC 7518) + * Cryptographic Algorithms for Key Management. Each standard algorithm is available as a + * ({@code public static final}) constant for direct type-safe reference in application code. For example: + *
+     * Jwts.builder()
+     *    // ... etc ...
+     *    .encryptWith(aKey, Jwe.enc.ECDH_ES_A256KW, Jwe.alg.A256GCM)
+     *    .build();
+ *

They are also available together as a {@link Registry} instance via the {@link #registry()} method.

+ * + * @see #registry() + * @since JJWT_RELEASE_VERSION + */ + final class enc { + + private static final String IMPL_CLASSNAME = "io.jsonwebtoken.impl.security.StandardKeyAlgorithms"; + private static final Registry> REGISTRY = Classes.newInstance(IMPL_CLASSNAME); + + /** + * Returns all standard JWA standard Cryptographic + * Algorithms for Key Management.. + * + * @return all standard JWA Key Management algorithms. + */ + public static Registry> registry() { + return REGISTRY; + } + + /** + * Key algorithm reflecting direct use of a shared symmetric key as the JWE AEAD encryption key, as defined + * by RFC 7518 (JWA), Section 4.5. This + * algorithm does not produce encrypted key ciphertext. + */ + public static final KeyAlgorithm DIRECT = Jwts.get(REGISTRY, "dir"); + + /** + * AES Key Wrap algorithm with default initial value using a 128-bit key, as defined by + * RFC 7518 (JWA), Section 4.4. + * + *

During JWE creation, this algorithm:

+ *
    + *
  1. Generates a new secure-random content encryption {@link SecretKey} suitable for use with a + * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  2. + *
  3. Encrypts this newly-generated {@code SecretKey} with a 128-bit shared symmetric key using the + * AES Key Wrap algorithm, producing encrypted key ciphertext.
  4. + *
  5. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated + * {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated {@link AeadAlgorithm}.
  6. + *
+ *

For JWE decryption, this algorithm:

+ *
    + *
  1. Obtains the encrypted key ciphertext embedded in the received JWE.
  2. + *
  3. Decrypts the encrypted key ciphertext with the 128-bit shared symmetric key, + * using the AES Key Unwrap algorithm, producing the decryption key plaintext.
  4. + *
  5. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire + * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  6. + *
+ */ + public static final SecretKeyAlgorithm A128KW = Jwts.get(REGISTRY, "A128KW"); + + /** + * AES Key Wrap algorithm with default initial value using a 192-bit key, as defined by + * RFC 7518 (JWA), Section 4.4. + * + *

During JWE creation, this algorithm:

+ *
    + *
  1. Generates a new secure-random content encryption {@link SecretKey} suitable for use with a + * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  2. + *
  3. Encrypts this newly-generated {@code SecretKey} with a 192-bit shared symmetric key using the + * AES Key Wrap algorithm, producing encrypted key ciphertext.
  4. + *
  5. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated + * {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated {@link AeadAlgorithm}.
  6. + *
+ *

For JWE decryption, this algorithm:

+ *
    + *
  1. Obtains the encrypted key ciphertext embedded in the received JWE.
  2. + *
  3. Decrypts the encrypted key ciphertext with the 192-bit shared symmetric key, + * using the AES Key Unwrap algorithm, producing the decryption key plaintext.
  4. + *
  5. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire + * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  6. + *
+ */ + public static final SecretKeyAlgorithm A192KW = Jwts.get(REGISTRY, "A192KW"); + + /** + * AES Key Wrap algorithm with default initial value using a 256-bit key, as defined by + * RFC 7518 (JWA), Section 4.4. + * + *

During JWE creation, this algorithm:

+ *
    + *
  1. Generates a new secure-random content encryption {@link SecretKey} suitable for use with a + * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  2. + *
  3. Encrypts this newly-generated {@code SecretKey} with a 256-bit shared symmetric key using the + * AES Key Wrap algorithm, producing encrypted key ciphertext.
  4. + *
  5. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated + * {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated {@link AeadAlgorithm}.
  6. + *
+ *

For JWE decryption, this algorithm:

+ *
    + *
  1. Obtains the encrypted key ciphertext embedded in the received JWE.
  2. + *
  3. Decrypts the encrypted key ciphertext with the 256-bit shared symmetric key, + * using the AES Key Unwrap algorithm, producing the decryption key plaintext.
  4. + *
  5. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire + * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  6. + *
+ */ + public static final SecretKeyAlgorithm A256KW = Jwts.get(REGISTRY, "A256KW"); + + /** + * Key wrap algorithm with AES GCM using a 128-bit key, as defined by + * RFC 7518 (JWA), Section 4.7. + * + *

During JWE creation, this algorithm:

+ *
    + *
  1. Generates a new secure-random content encryption {@link SecretKey} suitable for use with a + * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  2. + *
  3. Generates a new secure-random 96-bit Initialization Vector to use during key wrap/encryption.
  4. + *
  5. Encrypts this newly-generated {@code SecretKey} with a 128-bit shared symmetric key using the + * AES GCM Key Wrap algorithm with the generated Initialization Vector, producing encrypted key ciphertext + * and GCM authentication tag.
  6. + *
  7. Sets the generated initialization vector as the required + * "iv" + * (Initialization Vector) Header Parameter
  8. + *
  9. Sets the resulting GCM authentication tag as the required + * "tag" + * (Authentication Tag) Header Parameter
  10. + *
  11. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated + * {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated {@link AeadAlgorithm}.
  12. + *
+ *

For JWE decryption, this algorithm:

+ *
    + *
  1. Obtains the encrypted key ciphertext embedded in the received JWE.
  2. + *
  3. Obtains the required initialization vector from the + * "iv" + * (Initialization Vector) Header Parameter
  4. + *
  5. Obtains the required GCM authentication tag from the + * "tag" + * (Authentication Tag) Header Parameter
  6. + *
  7. Decrypts the encrypted key ciphertext with the 128-bit shared symmetric key, the initialization vector + * and GCM authentication tag using the AES GCM Key Unwrap algorithm, producing the decryption key + * plaintext.
  8. + *
  9. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire + * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  10. + *
+ */ + public static final SecretKeyAlgorithm A128GCMKW = Jwts.get(REGISTRY, "A128GCMKW"); + + /** + * Key wrap algorithm with AES GCM using a 192-bit key, as defined by + * RFC 7518 (JWA), Section 4.7. + * + *

During JWE creation, this algorithm:

+ *
    + *
  1. Generates a new secure-random content encryption {@link SecretKey} suitable for use with a + * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  2. + *
  3. Generates a new secure-random 96-bit Initialization Vector to use during key wrap/encryption.
  4. + *
  5. Encrypts this newly-generated {@code SecretKey} with a 192-bit shared symmetric key using the + * AES GCM Key Wrap algorithm with the generated Initialization Vector, producing encrypted key ciphertext + * and GCM authentication tag.
  6. + *
  7. Sets the generated initialization vector as the required + * "iv" + * (Initialization Vector) Header Parameter
  8. + *
  9. Sets the resulting GCM authentication tag as the required + * "tag" + * (Authentication Tag) Header Parameter
  10. + *
  11. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated + * {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated {@link AeadAlgorithm}.
  12. + *
+ *

For JWE decryption, this algorithm:

+ *
    + *
  1. Obtains the encrypted key ciphertext embedded in the received JWE.
  2. + *
  3. Obtains the required initialization vector from the + * "iv" + * (Initialization Vector) Header Parameter
  4. + *
  5. Obtains the required GCM authentication tag from the + * "tag" + * (Authentication Tag) Header Parameter
  6. + *
  7. Decrypts the encrypted key ciphertext with the 192-bit shared symmetric key, the initialization vector + * and GCM authentication tag using the AES GCM Key Unwrap algorithm, producing the decryption key \ + * plaintext.
  8. + *
  9. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire + * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  10. + *
+ */ + public static final SecretKeyAlgorithm A192GCMKW = Jwts.get(REGISTRY, "A192GCMKW"); + + /** + * Key wrap algorithm with AES GCM using a 256-bit key, as defined by + * RFC 7518 (JWA), Section 4.7. + * + *

During JWE creation, this algorithm:

+ *
    + *
  1. Generates a new secure-random content encryption {@link SecretKey} suitable for use with a + * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  2. + *
  3. Generates a new secure-random 96-bit Initialization Vector to use during key wrap/encryption.
  4. + *
  5. Encrypts this newly-generated {@code SecretKey} with a 256-bit shared symmetric key using the + * AES GCM Key Wrap algorithm with the generated Initialization Vector, producing encrypted key ciphertext + * and GCM authentication tag.
  6. + *
  7. Sets the generated initialization vector as the required + * "iv" + * (Initialization Vector) Header Parameter
  8. + *
  9. Sets the resulting GCM authentication tag as the required + * "tag" + * (Authentication Tag) Header Parameter
  10. + *
  11. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated + * {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated {@link AeadAlgorithm}.
  12. + *
+ *

For JWE decryption, this algorithm:

+ *
    + *
  1. Obtains the encrypted key ciphertext embedded in the received JWE.
  2. + *
  3. Obtains the required initialization vector from the + * "iv" + * (Initialization Vector) Header Parameter
  4. + *
  5. Obtains the required GCM authentication tag from the + * "tag" + * (Authentication Tag) Header Parameter
  6. + *
  7. Decrypts the encrypted key ciphertext with the 256-bit shared symmetric key, the initialization vector + * and GCM authentication tag using the AES GCM Key Unwrap algorithm, producing the decryption key \ + * plaintext.
  8. + *
  9. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire + * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  10. + *
+ */ + public static final SecretKeyAlgorithm A256GCMKW = Jwts.get(REGISTRY, "A256GCMKW"); + + /** + * Key encryption algorithm using PBES2 with HMAC SHA-256 and "A128KW" wrapping + * as defined by + * RFC 7518 (JWA), Section 4.8. + * + *

During JWE creation, this algorithm:

+ *
    + *
  1. Determines the number of PBDKF2 iterations via the JWE header's + * {@link JweHeader#getPbes2Count() pbes2Count} value. If that value is not set, a suitable number of + * iterations will be chosen based on + * OWASP + * PBKDF2 recommendations and then that value is set as the JWE header {@code pbes2Count} value.
  2. + *
  3. Generates a new secure-random salt input and sets it as the JWE header + * {@link JweHeader#getPbes2Salt() pbes2Salt} value.
  4. + *
  5. Derives a 128-bit Key Encryption Key with the PBES2-HS256 password-based key derivation algorithm, + * using the provided password, iteration count, and input salt as arguments.
  6. + *
  7. Generates a new secure-random Content Encryption {@link SecretKey} suitable for use with a + * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  8. + *
  9. Encrypts this newly-generated Content Encryption {@code SecretKey} with the {@code A128KW} key wrap + * algorithm using the 128-bit derived password-based Key Encryption Key from step {@code #3}, + * producing encrypted key ciphertext.
  10. + *
  11. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated + * Content Encryption {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated + * {@link AeadAlgorithm}.
  12. + *
+ *

For JWE decryption, this algorithm:

+ *
    + *
  1. Obtains the required PBKDF2 input salt from the + * "p2s" + * (PBES2 Salt Input) Header Parameter
  2. + *
  3. Obtains the required PBKDF2 iteration count from the + * "p2c" + * (PBES2 Count) Header Parameter
  4. + *
  5. Derives the 128-bit Key Encryption Key with the PBES2-HS256 password-based key derivation algorithm, + * using the provided password, obtained salt input, and obtained iteration count as arguments.
  6. + *
  7. Obtains the encrypted key ciphertext embedded in the received JWE.
  8. + *
  9. Decrypts the encrypted key ciphertext with with the {@code A128KW} key unwrap + * algorithm using the 128-bit derived password-based Key Encryption Key from step {@code #3}, + * producing the decryption key plaintext.
  10. + *
  11. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire + * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  12. + *
+ */ + public static final KeyAlgorithm PBES2_HS256_A128KW = Jwts.get(REGISTRY, "PBES2-HS256+A128KW"); + + /** + * Key encryption algorithm using PBES2 with HMAC SHA-384 and "A192KW" wrapping + * as defined by + * RFC 7518 (JWA), Section 4.8. + * + *

During JWE creation, this algorithm:

+ *
    + *
  1. Determines the number of PBDKF2 iterations via the JWE header's + * {@link JweHeader#getPbes2Count() pbes2Count} value. If that value is not set, a suitable number of + * iterations will be chosen based on + * OWASP + * PBKDF2 recommendations and then that value is set as the JWE header {@code pbes2Count} value.
  2. + *
  3. Generates a new secure-random salt input and sets it as the JWE header + * {@link JweHeader#getPbes2Salt() pbes2Salt} value.
  4. + *
  5. Derives a 192-bit Key Encryption Key with the PBES2-HS384 password-based key derivation algorithm, + * using the provided password, iteration count, and input salt as arguments.
  6. + *
  7. Generates a new secure-random Content Encryption {@link SecretKey} suitable for use with a + * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  8. + *
  9. Encrypts this newly-generated Content Encryption {@code SecretKey} with the {@code A192KW} key wrap + * algorithm using the 192-bit derived password-based Key Encryption Key from step {@code #3}, + * producing encrypted key ciphertext.
  10. + *
  11. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated + * Content Encryption {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated + * {@link AeadAlgorithm}.
  12. + *
+ *

For JWE decryption, this algorithm:

+ *
    + *
  1. Obtains the required PBKDF2 input salt from the + * "p2s" + * (PBES2 Salt Input) Header Parameter
  2. + *
  3. Obtains the required PBKDF2 iteration count from the + * "p2c" + * (PBES2 Count) Header Parameter
  4. + *
  5. Derives the 192-bit Key Encryption Key with the PBES2-HS384 password-based key derivation algorithm, + * using the provided password, obtained salt input, and obtained iteration count as arguments.
  6. + *
  7. Obtains the encrypted key ciphertext embedded in the received JWE.
  8. + *
  9. Decrypts the encrypted key ciphertext with with the {@code A192KW} key unwrap + * algorithm using the 192-bit derived password-based Key Encryption Key from step {@code #3}, + * producing the decryption key plaintext.
  10. + *
  11. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire + * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  12. + *
+ */ + public static final KeyAlgorithm PBES2_HS384_A192KW = Jwts.get(REGISTRY, "PBES2-HS384+A192KW"); + + /** + * Key encryption algorithm using PBES2 with HMAC SHA-512 and "A256KW" wrapping + * as defined by + * RFC 7518 (JWA), Section 4.8. + * + *

During JWE creation, this algorithm:

+ *
    + *
  1. Determines the number of PBDKF2 iterations via the JWE header's + * {@link JweHeader#getPbes2Count() pbes2Count} value. If that value is not set, a suitable number of + * iterations will be chosen based on + * OWASP + * PBKDF2 recommendations and then that value is set as the JWE header {@code pbes2Count} value.
  2. + *
  3. Generates a new secure-random salt input and sets it as the JWE header + * {@link JweHeader#getPbes2Salt() pbes2Salt} value.
  4. + *
  5. Derives a 256-bit Key Encryption Key with the PBES2-HS512 password-based key derivation algorithm, + * using the provided password, iteration count, and input salt as arguments.
  6. + *
  7. Generates a new secure-random Content Encryption {@link SecretKey} suitable for use with a + * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  8. + *
  9. Encrypts this newly-generated Content Encryption {@code SecretKey} with the {@code A256KW} key wrap + * algorithm using the 256-bit derived password-based Key Encryption Key from step {@code #3}, + * producing encrypted key ciphertext.
  10. + *
  11. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated + * Content Encryption {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated + * {@link AeadAlgorithm}.
  12. + *
+ *

For JWE decryption, this algorithm:

+ *
    + *
  1. Obtains the required PBKDF2 input salt from the + * "p2s" + * (PBES2 Salt Input) Header Parameter
  2. + *
  3. Obtains the required PBKDF2 iteration count from the + * "p2c" + * (PBES2 Count) Header Parameter
  4. + *
  5. Derives the 256-bit Key Encryption Key with the PBES2-HS512 password-based key derivation algorithm, + * using the provided password, obtained salt input, and obtained iteration count as arguments.
  6. + *
  7. Obtains the encrypted key ciphertext embedded in the received JWE.
  8. + *
  9. Decrypts the encrypted key ciphertext with with the {@code A256KW} key unwrap + * algorithm using the 256-bit derived password-based Key Encryption Key from step {@code #3}, + * producing the decryption key plaintext.
  10. + *
  11. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire + * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  12. + *
+ */ + public static final KeyAlgorithm PBES2_HS512_A256KW = Jwts.get(REGISTRY, "PBES2-HS512+A256KW"); + + /** + * Key Encryption with {@code RSAES-PKCS1-v1_5}, as defined by + * RFC 7518 (JWA), Section 4.2. + * This algorithm requires a key size of 2048 bits or larger. + * + *

During JWE creation, this algorithm:

+ *
    + *
  1. Generates a new secure-random content encryption {@link SecretKey} suitable for use with a + * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  2. + *
  3. Encrypts this newly-generated {@code SecretKey} with the RSA key wrap algorithm, using the JWE + * recipient's RSA Public Key, producing encrypted key ciphertext.
  4. + *
  5. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated + * {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated {@link AeadAlgorithm}.
  6. + *
+ *

For JWE decryption, this algorithm:

+ *
    + *
  1. Receives the encrypted key ciphertext embedded in the received JWE.
  2. + *
  3. Decrypts the encrypted key ciphertext with the RSA key unwrap algorithm, using the JWE recipient's + * RSA Private Key, producing the decryption key plaintext.
  4. + *
  5. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire + * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  6. + *
+ */ + public static final KeyAlgorithm RSA1_5 = Jwts.get(REGISTRY, "RSA1_5"); + + /** + * Key Encryption with {@code RSAES OAEP using default parameters}, as defined by + * RFC 7518 (JWA), Section 4.3. + * This algorithm requires a key size of 2048 bits or larger. + * + *

During JWE creation, this algorithm:

+ *
    + *
  1. Generates a new secure-random content encryption {@link SecretKey} suitable for use with a + * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  2. + *
  3. Encrypts this newly-generated {@code SecretKey} with the RSA OAEP with SHA-1 and MGF1 key wrap algorithm, + * using the JWE recipient's RSA Public Key, producing encrypted key ciphertext.
  4. + *
  5. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated + * {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated {@link AeadAlgorithm}.
  6. + *
+ *

For JWE decryption, this algorithm:

+ *
    + *
  1. Receives the encrypted key ciphertext embedded in the received JWE.
  2. + *
  3. Decrypts the encrypted key ciphertext with the RSA OAEP with SHA-1 and MGF1 key unwrap algorithm, + * using the JWE recipient's RSA Private Key, producing the decryption key plaintext.
  4. + *
  5. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire + * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  6. + *
+ */ + public static final KeyAlgorithm RSA_OAEP = Jwts.get(REGISTRY, "RSA-OAEP"); + + /** + * Key Encryption with {@code RSAES OAEP using SHA-256 and MGF1 with SHA-256}, as defined by + * RFC 7518 (JWA), Section 4.3. + * This algorithm requires a key size of 2048 bits or larger. + * + *

During JWE creation, this algorithm:

+ *
    + *
  1. Generates a new secure-random content encryption {@link SecretKey} suitable for use with a + * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  2. + *
  3. Encrypts this newly-generated {@code SecretKey} with the RSA OAEP with SHA-256 and MGF1 key wrap + * algorithm, using the JWE recipient's RSA Public Key, producing encrypted key ciphertext.
  4. + *
  5. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated + * {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated {@link AeadAlgorithm}.
  6. + *
+ *

For JWE decryption, this algorithm:

+ *
    + *
  1. Receives the encrypted key ciphertext embedded in the received JWE.
  2. + *
  3. Decrypts the encrypted key ciphertext with the RSA OAEP with SHA-256 and MGF1 key unwrap algorithm, + * using the JWE recipient's RSA Private Key, producing the decryption key plaintext.
  4. + *
  5. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire + * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  6. + *
+ */ + public static final KeyAlgorithm RSA_OAEP_256 = Jwts.get(REGISTRY, "RSA-OAEP-256"); + + /** + * Key Agreement with {@code ECDH-ES using Concat KDF} as defined by + * RFC 7518 (JWA), Section 4.6. + * + *

During JWE creation, this algorithm:

+ *
    + *
  1. Generates a new secure-random Elliptic Curve public/private key pair on the same curve as the + * JWE recipient's EC Public Key.
  2. + *
  3. Generates a shared secret with the ECDH key agreement algorithm using the generated EC Private Key + * and the JWE recipient's EC Public Key.
  4. + *
  5. Derives a symmetric Content + * Encryption {@code SecretKey} with the Concat KDF algorithm using the + * generated shared secret and any available + * {@link JweHeader#getAgreementPartyUInfo() PartyUInfo} and + * {@link JweHeader#getAgreementPartyVInfo() PartyVInfo}.
  6. + *
  7. Sets the generated EC key pair's Public Key as the required + * "epk" + * (Ephemeral Public Key) Header Parameter to be transmitted in the JWE.
  8. + *
  9. Returns the derived symmetric {@code SecretKey} for JJWT to use to encrypt the entire JWE with the + * associated {@link AeadAlgorithm}. Encrypted key ciphertext is not produced with this algorithm, so + * the resulting JWE will not contain any embedded key ciphertext.
  10. + *
+ *

For JWE decryption, this algorithm:

+ *
    + *
  1. Obtains the required ephemeral Elliptic Curve Public Key from the + * "epk" + * (Ephemeral Public Key) Header Parameter.
  2. + *
  3. Validates that the ephemeral Public Key is on the same curve as the recipient's EC Private Key.
  4. + *
  5. Obtains the shared secret with the ECDH key agreement algorithm using the obtained EC Public Key + * and the JWE recipient's EC Private Key.
  6. + *
  7. Derives the symmetric Content + * Encryption {@code SecretKey} with the Concat KDF algorithm using the + * obtained shared secret and any available + * {@link JweHeader#getAgreementPartyUInfo() PartyUInfo} and + * {@link JweHeader#getAgreementPartyVInfo() PartyVInfo}.
  8. + *
  9. Returns the derived symmetric {@code SecretKey} for JJWT to use to decrypt the entire + * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  10. + *
+ */ + public static final KeyAlgorithm ECDH_ES = Jwts.get(REGISTRY, "ECDH-ES"); + + /** + * Key Agreement with Key Wrapping via + * ECDH-ES using Concat KDF and CEK wrapped with "A128KW" as defined by + * RFC 7518 (JWA), Section 4.6. + * + *

During JWE creation, this algorithm:

+ *
    + *
  1. Generates a new secure-random Elliptic Curve public/private key pair on the same curve as the + * JWE recipient's EC Public Key.
  2. + *
  3. Generates a shared secret with the ECDH key agreement algorithm using the generated EC Private Key + * and the JWE recipient's EC Public Key.
  4. + *
  5. Derives a 128-bit symmetric Key + * Encryption {@code SecretKey} with the Concat KDF algorithm using the + * generated shared secret and any available + * {@link JweHeader#getAgreementPartyUInfo() PartyUInfo} and + * {@link JweHeader#getAgreementPartyVInfo() PartyVInfo}.
  6. + *
  7. Sets the generated EC key pair's Public Key as the required + * "epk" + * (Ephemeral Public Key) Header Parameter to be transmitted in the JWE.
  8. + *
  9. Generates a new secure-random content encryption {@link SecretKey} suitable for use with a + * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  10. + *
  11. Encrypts this newly-generated {@code SecretKey} with the {@code A128KW} key wrap + * algorithm using the derived symmetric Key Encryption Key from step {@code #3}, producing encrypted key ciphertext.
  12. + *
  13. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated + * {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated {@link AeadAlgorithm}.
  14. + *
+ *

For JWE decryption, this algorithm:

+ *
    + *
  1. Obtains the required ephemeral Elliptic Curve Public Key from the + * "epk" + * (Ephemeral Public Key) Header Parameter.
  2. + *
  3. Validates that the ephemeral Public Key is on the same curve as the recipient's EC Private Key.
  4. + *
  5. Obtains the shared secret with the ECDH key agreement algorithm using the obtained EC Public Key + * and the JWE recipient's EC Private Key.
  6. + *
  7. Derives the symmetric Key + * Encryption {@code SecretKey} with the Concat KDF algorithm using the + * obtained shared secret and any available + * {@link JweHeader#getAgreementPartyUInfo() PartyUInfo} and + * {@link JweHeader#getAgreementPartyVInfo() PartyVInfo}.
  8. + *
  9. Obtains the encrypted key ciphertext embedded in the received JWE.
  10. + *
  11. Decrypts the encrypted key ciphertext with the AES Key Unwrap algorithm using the + * 128-bit derived symmetric key from step {@code #4}, producing the decryption key plaintext.
  12. + *
  13. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire + * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  14. + *
+ */ + public static final KeyAlgorithm ECDH_ES_A128KW = Jwts.get(REGISTRY, "ECDH-ES+A128KW"); + + /** + * Key Agreement with Key Wrapping via + * ECDH-ES using Concat KDF and CEK wrapped with "A192KW" as defined by + * RFC 7518 (JWA), Section 4.6. + * + *

During JWE creation, this algorithm:

+ *
    + *
  1. Generates a new secure-random Elliptic Curve public/private key pair on the same curve as the + * JWE recipient's EC Public Key.
  2. + *
  3. Generates a shared secret with the ECDH key agreement algorithm using the generated EC Private Key + * and the JWE recipient's EC Public Key.
  4. + *
  5. Derives a 192-bit symmetric Key + * Encryption {@code SecretKey} with the Concat KDF algorithm using the + * generated shared secret and any available + * {@link JweHeader#getAgreementPartyUInfo() PartyUInfo} and + * {@link JweHeader#getAgreementPartyVInfo() PartyVInfo}.
  6. + *
  7. Sets the generated EC key pair's Public Key as the required + * "epk" + * (Ephemeral Public Key) Header Parameter to be transmitted in the JWE.
  8. + *
  9. Generates a new secure-random content encryption {@link SecretKey} suitable for use with a + * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  10. + *
  11. Encrypts this newly-generated {@code SecretKey} with the {@code A192KW} key wrap + * algorithm using the derived symmetric Key Encryption Key from step {@code #3}, producing encrypted key + * ciphertext.
  12. + *
  13. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated + * {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated {@link AeadAlgorithm}.
  14. + *
+ *

For JWE decryption, this algorithm:

+ *
    + *
  1. Obtains the required ephemeral Elliptic Curve Public Key from the + * "epk" + * (Ephemeral Public Key) Header Parameter.
  2. + *
  3. Validates that the ephemeral Public Key is on the same curve as the recipient's EC Private Key.
  4. + *
  5. Obtains the shared secret with the ECDH key agreement algorithm using the obtained EC Public Key + * and the JWE recipient's EC Private Key.
  6. + *
  7. Derives the 192-bit symmetric + * Key Encryption {@code SecretKey} with the Concat KDF algorithm using the + * obtained shared secret and any available + * {@link JweHeader#getAgreementPartyUInfo() PartyUInfo} and + * {@link JweHeader#getAgreementPartyVInfo() PartyVInfo}.
  8. + *
  9. Obtains the encrypted key ciphertext embedded in the received JWE.
  10. + *
  11. Decrypts the encrypted key ciphertext with the AES Key Unwrap algorithm using the + * 192-bit derived symmetric key from step {@code #4}, producing the decryption key plaintext.
  12. + *
  13. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire + * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  14. + *
+ */ + public static final KeyAlgorithm ECDH_ES_A192KW = Jwts.get(REGISTRY, "ECDH-ES+A192KW"); + + /** + * Key Agreement with Key Wrapping via + * ECDH-ES using Concat KDF and CEK wrapped with "A256KW" as defined by + * RFC 7518 (JWA), Section 4.6. + * + *

During JWE creation, this algorithm:

+ *
    + *
  1. Generates a new secure-random Elliptic Curve public/private key pair on the same curve as the + * JWE recipient's EC Public Key.
  2. + *
  3. Generates a shared secret with the ECDH key agreement algorithm using the generated EC Private Key + * and the JWE recipient's EC Public Key.
  4. + *
  5. Derives a 256-bit symmetric Key + * Encryption {@code SecretKey} with the Concat KDF algorithm using the + * generated shared secret and any available + * {@link JweHeader#getAgreementPartyUInfo() PartyUInfo} and + * {@link JweHeader#getAgreementPartyVInfo() PartyVInfo}.
  6. + *
  7. Sets the generated EC key pair's Public Key as the required + * "epk" + * (Ephemeral Public Key) Header Parameter to be transmitted in the JWE.
  8. + *
  9. Generates a new secure-random content encryption {@link SecretKey} suitable for use with a + * specified {@link AeadAlgorithm} (using {@link AeadAlgorithm#key()}).
  10. + *
  11. Encrypts this newly-generated {@code SecretKey} with the {@code A256KW} key wrap + * algorithm using the derived symmetric Key Encryption Key from step {@code #3}, producing encrypted key + * ciphertext.
  12. + *
  13. Returns the encrypted key ciphertext for inclusion in the final JWE as well as the newly-generated + * {@code SecretKey} for JJWT to use to encrypt the entire JWE with associated {@link AeadAlgorithm}.
  14. + *
+ *

For JWE decryption, this algorithm:

+ *
    + *
  1. Obtains the required ephemeral Elliptic Curve Public Key from the + * "epk" + * (Ephemeral Public Key) Header Parameter.
  2. + *
  3. Validates that the ephemeral Public Key is on the same curve as the recipient's EC Private Key.
  4. + *
  5. Obtains the shared secret with the ECDH key agreement algorithm using the obtained EC Public Key + * and the JWE recipient's EC Private Key.
  6. + *
  7. Derives the 256-bit symmetric + * Key Encryption {@code SecretKey} with the Concat KDF algorithm using the + * obtained shared secret and any available + * {@link JweHeader#getAgreementPartyUInfo() PartyUInfo} and + * {@link JweHeader#getAgreementPartyVInfo() PartyVInfo}.
  8. + *
  9. Obtains the encrypted key ciphertext embedded in the received JWE.
  10. + *
  11. Decrypts the encrypted key ciphertext with the AES Key Unwrap algorithm using the + * 256-bit derived symmetric key from step {@code #4}, producing the decryption key plaintext.
  12. + *
  13. Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire + * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
  14. + *
+ */ + public static final KeyAlgorithm ECDH_ES_A256KW = Jwts.get(REGISTRY, "ECDH-ES+A256KW"); + + //prevent instantiation + private enc() { + } + } + /** * Visitor implementation that ensures the visited JWT is a JSON Web Encryption ('JWE') message with an * authenticated and decrypted {@code byte[]} array payload, and rejects all others with an diff --git a/api/src/main/java/io/jsonwebtoken/JweHeader.java b/api/src/main/java/io/jsonwebtoken/JweHeader.java index 8ba6b7f7d..40d8dcd33 100644 --- a/api/src/main/java/io/jsonwebtoken/JweHeader.java +++ b/api/src/main/java/io/jsonwebtoken/JweHeader.java @@ -65,11 +65,11 @@ public interface JweHeader extends ProtectedHeader { * @return the {@code epk} (Ephemeral * Public Key) header value created by the JWE originator for use with key agreement algorithms, or * {@code null} if not present. - * @see Jwts.KEY - * @see Jwts.KEY#ECDH_ES - * @see Jwts.KEY#ECDH_ES_A128KW - * @see Jwts.KEY#ECDH_ES_A192KW - * @see Jwts.KEY#ECDH_ES_A256KW + * @see Jwe.enc + * @see Jwe.enc#ECDH_ES + * @see Jwe.enc#ECDH_ES_A128KW + * @see Jwe.enc#ECDH_ES_A192KW + * @see Jwe.enc#ECDH_ES_A256KW */ PublicJwk getEphemeralPublicKey(); @@ -80,10 +80,10 @@ public interface JweHeader extends ProtectedHeader { * @return any information about the JWE producer for use with key agreement algorithms, or {@code null} if not * present. * @see JWE apu (Agreement PartyUInfo) Header Parameter - * @see Jwts.KEY#ECDH_ES - * @see Jwts.KEY#ECDH_ES_A128KW - * @see Jwts.KEY#ECDH_ES_A192KW - * @see Jwts.KEY#ECDH_ES_A256KW + * @see Jwe.enc#ECDH_ES + * @see Jwe.enc#ECDH_ES_A128KW + * @see Jwe.enc#ECDH_ES_A192KW + * @see Jwe.enc#ECDH_ES_A256KW */ byte[] getAgreementPartyUInfo(); @@ -94,10 +94,10 @@ public interface JweHeader extends ProtectedHeader { * @return any information about the JWE recipient for use with key agreement algorithms, or {@code null} if not * present. * @see JWE apv (Agreement PartyVInfo) Header Parameter - * @see Jwts.KEY#ECDH_ES - * @see Jwts.KEY#ECDH_ES_A128KW - * @see Jwts.KEY#ECDH_ES_A192KW - * @see Jwts.KEY#ECDH_ES_A256KW + * @see Jwe.enc#ECDH_ES + * @see Jwe.enc#ECDH_ES_A128KW + * @see Jwe.enc#ECDH_ES_A192KW + * @see Jwe.enc#ECDH_ES_A256KW */ byte[] getAgreementPartyVInfo(); @@ -113,9 +113,9 @@ public interface JweHeader extends ProtectedHeader { * automatically when producing the encryption key.

* * @return the 96-bit initialization vector generated during key encryption, or {@code null} if not present. - * @see Jwts.KEY#A128GCMKW - * @see Jwts.KEY#A192GCMKW - * @see Jwts.KEY#A256GCMKW + * @see Jwe.enc#A128GCMKW + * @see Jwe.enc#A192GCMKW + * @see Jwe.enc#A256GCMKW */ byte[] getInitializationVector(); @@ -130,9 +130,9 @@ public interface JweHeader extends ProtectedHeader { * automatically when producing the encryption key.

* * @return the 128-bit authentication tag resulting from key encryption, or {@code null} if not present. - * @see Jwts.KEY#A128GCMKW - * @see Jwts.KEY#A192GCMKW - * @see Jwts.KEY#A256GCMKW + * @see Jwe.enc#A128GCMKW + * @see Jwe.enc#A192GCMKW + * @see Jwe.enc#A256GCMKW */ byte[] getAuthenticationTag(); @@ -143,9 +143,9 @@ public interface JweHeader extends ProtectedHeader { * @return the number of PBKDF2 iterations necessary to derive the key used during JWE encryption, or {@code null} * if not present. * @see JWE p2c (PBES2 Count) Header Parameter - * @see Jwts.KEY#PBES2_HS256_A128KW - * @see Jwts.KEY#PBES2_HS384_A192KW - * @see Jwts.KEY#PBES2_HS512_A256KW + * @see Jwe.enc#PBES2_HS256_A128KW + * @see Jwe.enc#PBES2_HS384_A192KW + * @see Jwe.enc#PBES2_HS512_A256KW */ Integer getPbes2Count(); @@ -162,9 +162,9 @@ public interface JweHeader extends ProtectedHeader { * @return the PBKDF2 {@code Salt Input} value necessary to derive the key used during JWE encryption, or * {@code null} if not present. * @see JWE p2s (PBES2 Salt Input) Header Parameter - * @see Jwts.KEY#PBES2_HS256_A128KW - * @see Jwts.KEY#PBES2_HS384_A192KW - * @see Jwts.KEY#PBES2_HS512_A256KW + * @see Jwe.enc#PBES2_HS256_A128KW + * @see Jwe.enc#PBES2_HS384_A192KW + * @see Jwe.enc#PBES2_HS512_A256KW */ byte[] getPbes2Salt(); } diff --git a/api/src/main/java/io/jsonwebtoken/JweHeaderMutator.java b/api/src/main/java/io/jsonwebtoken/JweHeaderMutator.java index 912136d66..e0a2e414c 100644 --- a/api/src/main/java/io/jsonwebtoken/JweHeaderMutator.java +++ b/api/src/main/java/io/jsonwebtoken/JweHeaderMutator.java @@ -32,10 +32,10 @@ public interface JweHeaderMutator> extends Protect * @param info information about the JWE producer to use with key agreement algorithms. * @return the header for method chaining. * @see JWE apu (Agreement PartyUInfo) Header Parameter - * @see Jwts.KEY#ECDH_ES - * @see Jwts.KEY#ECDH_ES_A128KW - * @see Jwts.KEY#ECDH_ES_A192KW - * @see Jwts.KEY#ECDH_ES_A256KW + * @see Jwe.enc#ECDH_ES + * @see Jwe.enc#ECDH_ES_A128KW + * @see Jwe.enc#ECDH_ES_A192KW + * @see Jwe.enc#ECDH_ES_A256KW */ T agreementPartyUInfo(byte[] info); @@ -50,10 +50,10 @@ public interface JweHeaderMutator> extends Protect * @param info information about the JWE producer to use with key agreement algorithms. * @return the header for method chaining. * @see JWE apu (Agreement PartyUInfo) Header Parameter - * @see Jwts.KEY#ECDH_ES - * @see Jwts.KEY#ECDH_ES_A128KW - * @see Jwts.KEY#ECDH_ES_A192KW - * @see Jwts.KEY#ECDH_ES_A256KW + * @see Jwe.enc#ECDH_ES + * @see Jwe.enc#ECDH_ES_A128KW + * @see Jwe.enc#ECDH_ES_A192KW + * @see Jwe.enc#ECDH_ES_A256KW */ T agreementPartyUInfo(String info); @@ -64,10 +64,10 @@ public interface JweHeaderMutator> extends Protect * @param info information about the JWE recipient to use with key agreement algorithms. * @return the header for method chaining. * @see JWE apv (Agreement PartyVInfo) Header Parameter - * @see Jwts.KEY#ECDH_ES - * @see Jwts.KEY#ECDH_ES_A128KW - * @see Jwts.KEY#ECDH_ES_A192KW - * @see Jwts.KEY#ECDH_ES_A256KW + * @see Jwe.enc#ECDH_ES + * @see Jwe.enc#ECDH_ES_A128KW + * @see Jwe.enc#ECDH_ES_A192KW + * @see Jwe.enc#ECDH_ES_A256KW */ T agreementPartyVInfo(byte[] info); @@ -82,10 +82,10 @@ public interface JweHeaderMutator> extends Protect * @param info information about the JWE recipient to use with key agreement algorithms. * @return the header for method chaining. * @see JWE apv (Agreement PartyVInfo) Header Parameter - * @see Jwts.KEY#ECDH_ES - * @see Jwts.KEY#ECDH_ES_A128KW - * @see Jwts.KEY#ECDH_ES_A192KW - * @see Jwts.KEY#ECDH_ES_A256KW + * @see Jwe.enc#ECDH_ES + * @see Jwe.enc#ECDH_ES_A128KW + * @see Jwe.enc#ECDH_ES_A192KW + * @see Jwe.enc#ECDH_ES_A256KW */ T agreementPartyVInfo(String info); @@ -107,9 +107,9 @@ public interface JweHeaderMutator> extends Protect * greater than or equal to 1000 (one thousand). * @return the header for method chaining * @see JWE p2c (PBES2 Count) Header Parameter - * @see Jwts.KEY#PBES2_HS256_A128KW - * @see Jwts.KEY#PBES2_HS384_A192KW - * @see Jwts.KEY#PBES2_HS512_A256KW + * @see Jwe.enc#PBES2_HS256_A128KW + * @see Jwe.enc#PBES2_HS384_A192KW + * @see Jwe.enc#PBES2_HS512_A256KW * @see OWASP PBKDF2 Iteration Recommendations */ T pbes2Count(int count); diff --git a/api/src/main/java/io/jsonwebtoken/Jws.java b/api/src/main/java/io/jsonwebtoken/Jws.java index 8c6010c1e..85fab5a5a 100644 --- a/api/src/main/java/io/jsonwebtoken/Jws.java +++ b/api/src/main/java/io/jsonwebtoken/Jws.java @@ -15,6 +15,14 @@ */ package io.jsonwebtoken; +import io.jsonwebtoken.lang.Classes; +import io.jsonwebtoken.lang.Registry; +import io.jsonwebtoken.security.KeyPairBuilderSupplier; +import io.jsonwebtoken.security.MacAlgorithm; +import io.jsonwebtoken.security.SecureDigestAlgorithm; + +import java.security.Key; + /** * An expanded (not compact/serialized) Signed JSON Web Token. * @@ -23,6 +31,169 @@ */ public interface Jws

extends ProtectedJwt { + /** + * Constants for all JWA (RFC 7518) standard + * Cryptographic Algorithms for Digital Signatures and MACs defined in the + * JSON Web Signature and Encryption Algorithms + * Registry. Each standard algorithm is available as a ({@code public static final}) constant for + * direct type-safe reference in application code. For example: + *

+     * Jwts.builder()
+     *    // ... etc ...
+     *    .signWith(aKey, Jws.alg.HS512) // or RS512, PS256, EdDSA, etc...
+     *    .build();
+ *

They are also available together as a {@link Registry} instance via the {@link #registry()} method.

+ * + * @see #registry() + * @since JJWT_RELEASE_VERSION + */ + final class alg { + + private static final String IMPL_CLASSNAME = "io.jsonwebtoken.impl.security.StandardSecureDigestAlgorithms"; + private static final Registry> REGISTRY = Classes.newInstance(IMPL_CLASSNAME); + + //prevent instantiation + private alg() { + } + + /** + * Returns all standard JWA Cryptographic + * Algorithms for Digital Signatures and MACs defined in the + * JSON Web Signature and Encryption + * Algorithms Registry. + * + * @return all standard JWA digital signature and MAC algorithms. + */ + public static Registry> registry() { + return REGISTRY; + } + + /** + * The "none" signature algorithm as defined by + * RFC 7518, Section 3.6. This algorithm + * is used only when creating unsecured (not integrity protected) JWSs and is not usable in any other scenario. + * Any attempt to call its methods will result in an exception being thrown. + */ + public static final SecureDigestAlgorithm NONE = Jwts.get(REGISTRY, "none"); + + /** + * {@code HMAC using SHA-256} message authentication algorithm as defined by + * RFC 7518, Section 3.2. This algorithm + * requires a 256-bit (32 byte) key. + */ + public static final MacAlgorithm HS256 = Jwts.get(REGISTRY, "HS256"); + + /** + * {@code HMAC using SHA-384} message authentication algorithm as defined by + * RFC 7518, Section 3.2. This algorithm + * requires a 384-bit (48 byte) key. + */ + public static final MacAlgorithm HS384 = Jwts.get(REGISTRY, "HS384"); + + /** + * {@code HMAC using SHA-512} message authentication algorithm as defined by + * RFC 7518, Section 3.2. This algorithm + * requires a 512-bit (64 byte) key. + */ + public static final MacAlgorithm HS512 = Jwts.get(REGISTRY, "HS512"); + + /** + * {@code RSASSA-PKCS1-v1_5 using SHA-256} signature algorithm as defined by + * RFC 7518, Section 3.3. This algorithm + * requires a 2048-bit key. + */ + public static final io.jsonwebtoken.security.SignatureAlgorithm RS256 = Jwts.get(REGISTRY, "RS256"); + + /** + * {@code RSASSA-PKCS1-v1_5 using SHA-384} signature algorithm as defined by + * RFC 7518, Section 3.3. This algorithm + * requires a 2048-bit key, but the JJWT team recommends a 3072-bit key. + */ + public static final io.jsonwebtoken.security.SignatureAlgorithm RS384 = Jwts.get(REGISTRY, "RS384"); + + /** + * {@code RSASSA-PKCS1-v1_5 using SHA-512} signature algorithm as defined by + * RFC 7518, Section 3.3. This algorithm + * requires a 2048-bit key, but the JJWT team recommends a 4096-bit key. + */ + public static final io.jsonwebtoken.security.SignatureAlgorithm RS512 = Jwts.get(REGISTRY, "RS512"); + + /** + * {@code RSASSA-PSS using SHA-256 and MGF1 with SHA-256} signature algorithm as defined by + * RFC 7518, Section 3.51. + * This algorithm requires a 2048-bit key. + * + *

1 Requires Java 11 or a compatible JCA Provider (like BouncyCastle) in the runtime + * classpath. If on Java 10 or earlier, BouncyCastle will be used automatically if found in the runtime + * classpath.

+ */ + public static final io.jsonwebtoken.security.SignatureAlgorithm PS256 = Jwts.get(REGISTRY, "PS256"); + + /** + * {@code RSASSA-PSS using SHA-384 and MGF1 with SHA-384} signature algorithm as defined by + * RFC 7518, Section 3.51. + * This algorithm requires a 2048-bit key, but the JJWT team recommends a 3072-bit key. + * + *

1 Requires Java 11 or a compatible JCA Provider (like BouncyCastle) in the runtime + * classpath. If on Java 10 or earlier, BouncyCastle will be used automatically if found in the runtime + * classpath.

+ */ + public static final io.jsonwebtoken.security.SignatureAlgorithm PS384 = Jwts.get(REGISTRY, "PS384"); + + /** + * {@code RSASSA-PSS using SHA-512 and MGF1 with SHA-512} signature algorithm as defined by + * RFC 7518, Section 3.51. + * This algorithm requires a 2048-bit key, but the JJWT team recommends a 4096-bit key. + * + *

1 Requires Java 11 or a compatible JCA Provider (like BouncyCastle) in the runtime + * classpath. If on Java 10 or earlier, BouncyCastle will be used automatically if found in the runtime + * classpath.

+ */ + public static final io.jsonwebtoken.security.SignatureAlgorithm PS512 = Jwts.get(REGISTRY, "PS512"); + + /** + * {@code ECDSA using P-256 and SHA-256} signature algorithm as defined by + * RFC 7518, Section 3.4. This algorithm + * requires a 256-bit key. + */ + public static final io.jsonwebtoken.security.SignatureAlgorithm ES256 = Jwts.get(REGISTRY, "ES256"); + + /** + * {@code ECDSA using P-384 and SHA-384} signature algorithm as defined by + * RFC 7518, Section 3.4. This algorithm + * requires a 384-bit key. + */ + public static final io.jsonwebtoken.security.SignatureAlgorithm ES384 = Jwts.get(REGISTRY, "ES384"); + + /** + * {@code ECDSA using P-521 and SHA-512} signature algorithm as defined by + * RFC 7518, Section 3.4. This algorithm + * requires a 521-bit key. + */ + public static final io.jsonwebtoken.security.SignatureAlgorithm ES512 = Jwts.get(REGISTRY, "ES512"); + + /** + * {@code EdDSA} signature algorithm defined by + * RFC 8037, Section 3.1 that requires + * either {@code Ed25519} or {@code Ed448} Edwards Elliptic Curve1 keys. + * + *

KeyPair Generation

+ * + *

This instance's {@link KeyPairBuilderSupplier#keyPair() keyPair()} builder creates {@code Ed448} keys, + * and is essentially an alias for + * {@link io.jsonwebtoken.security.Jwks.CRV Jwks.CRV}.{@link io.jsonwebtoken.security.Jwks.CRV#Ed448 Ed448}.{@link KeyPairBuilderSupplier#keyPair() keyPair()}.

+ * + *

If you would like to generate an {@code Ed25519} {@code KeyPair} for use with the {@code EdDSA} algorithm, + * you may use the + * {@link io.jsonwebtoken.security.Jwks.CRV Jwks.CRV}.{@link io.jsonwebtoken.security.Jwks.CRV#Ed25519 Ed25519}.{@link KeyPairBuilderSupplier#keyPair() keyPair()} + * builder instead.

+ * + *

1This algorithm requires at least JDK 15 or a compatible JCA Provider (like BouncyCastle) in the runtime + * classpath.

+ */ + public static final io.jsonwebtoken.security.SignatureAlgorithm EdDSA = Jwts.get(REGISTRY, "EdDSA"); + } + /** * Visitor implementation that ensures the visited JWT is a JSON Web Signature ('JWS') message with a * cryptographically authenticated/verified {@code byte[]} array payload, and rejects all others with an diff --git a/api/src/main/java/io/jsonwebtoken/JwtBuilder.java b/api/src/main/java/io/jsonwebtoken/JwtBuilder.java index 634800851..0e4f10ecb 100644 --- a/api/src/main/java/io/jsonwebtoken/JwtBuilder.java +++ b/api/src/main/java/io/jsonwebtoken/JwtBuilder.java @@ -612,61 +612,61 @@ public interface JwtBuilder extends ClaimsMutator { * {@link SecretKey} * {@link Key#getAlgorithm() getAlgorithm()}.equals("HmacSHA256")1 * 256 <= size <= 383 2 - * {@link Jwts.SIG#HS256 HS256} + * {@link Jws.alg#HS256 HS256} * * * {@link SecretKey} * {@link Key#getAlgorithm() getAlgorithm()}.equals("HmacSHA384")1 * 384 <= size <= 511 - * {@link Jwts.SIG#HS384 HS384} + * {@link Jws.alg#HS384 HS384} * * * {@link SecretKey} * {@link Key#getAlgorithm() getAlgorithm()}.equals("HmacSHA512")1 * 512 <= size - * {@link Jwts.SIG#HS512 HS512} + * {@link Jws.alg#HS512 HS512} * * * {@link ECKey} * instanceof {@link PrivateKey} * 256 <= size <= 383 3 - * {@link Jwts.SIG#ES256 ES256} + * {@link Jws.alg#ES256 ES256} * * * {@link ECKey} * instanceof {@link PrivateKey} * 384 <= size <= 520 4 - * {@link Jwts.SIG#ES384 ES384} + * {@link Jws.alg#ES384 ES384} * * * {@link ECKey} * instanceof {@link PrivateKey} * 521 <= size 4 - * {@link Jwts.SIG#ES512 ES512} + * {@link Jws.alg#ES512 ES512} * * * {@link RSAKey} * instanceof {@link PrivateKey} * 2048 <= size <= 3071 5,6 - * {@link Jwts.SIG#RS256 RS256} + * {@link Jws.alg#RS256 RS256} * * * {@link RSAKey} * instanceof {@link PrivateKey} * 3072 <= size <= 4095 6 - * {@link Jwts.SIG#RS384 RS384} + * {@link Jws.alg#RS384 RS384} * * * {@link RSAKey} * instanceof {@link PrivateKey} * 4096 <= size 5 - * {@link Jwts.SIG#RS512 RS512} + * {@link Jws.alg#RS512 RS512} * * * EdECKey7 * instanceof {@link PrivateKey} * 256 || 456 - * {@link Jwts.SIG#EdDSA EdDSA} + * {@link Jws.alg#EdDSA EdDSA} * * * @@ -692,18 +692,18 @@ public interface JwtBuilder extends ClaimsMutator { * {@code RSAKey}s with key lengths less than 2048 bits will be rejected with a * {@link WeakKeyException}. *
  • Technically any RSA key of length >= 2048 bits may be used with the - * {@link Jwts.SIG#RS256 RS256}, {@link Jwts.SIG#RS384 RS384}, and - * {@link Jwts.SIG#RS512 RS512} algorithms, so we assume an RSA signature algorithm based on the key + * {@link Jws.alg#RS256 RS256}, {@link Jws.alg#RS384 RS384}, and + * {@link Jws.alg#RS512 RS512} algorithms, so we assume an RSA signature algorithm based on the key * length to parallel similar decisions in the JWT specification for HMAC and ECDSA signature algorithms. * This is not required - just a convenience.
  • *
  • EdECKeys * require JDK >= 15 or BouncyCastle in the runtime classpath.
  • * * - *

    This implementation does not use the {@link Jwts.SIG#PS256 PS256}, - * {@link Jwts.SIG#PS384 PS384}, or {@link Jwts.SIG#PS512 PS512} RSA variants for any - * specified {@link RSAKey} because the the {@link Jwts.SIG#RS256 RS256}, - * {@link Jwts.SIG#RS384 RS384}, and {@link Jwts.SIG#RS512 RS512} algorithms are + *

    This implementation does not use the {@link Jws.alg#PS256 PS256}, + * {@link Jws.alg#PS384 PS384}, or {@link Jws.alg#PS512 PS512} RSA variants for any + * specified {@link RSAKey} because the the {@link Jws.alg#RS256 RS256}, + * {@link Jws.alg#RS384 RS384}, and {@link Jws.alg#RS512 RS512} algorithms are * available in the JDK by default while the {@code PS}* variants require either JDK 11 or an additional JCA * Provider (like BouncyCastle). If you wish to use a {@code PS}* variant with your key, use the * {@link #signWith(Key, SecureDigestAlgorithm)} method instead.

    @@ -716,7 +716,7 @@ public interface JwtBuilder extends ClaimsMutator { * @return the builder instance for method chaining. * @throws InvalidKeyException if the Key is insufficient, unsupported, or explicitly disallowed by the JWT * specification as described above in recommended signature algorithms. - * @see Jwts.SIG + * @see Jws.alg * @see #signWith(Key, SecureDigestAlgorithm) * @since 0.10.0 */ @@ -817,7 +817,7 @@ public interface JwtBuilder extends ClaimsMutator { * *

    This has been deprecated since 0.12.0. Use * {@link #signWith(Key, SecureDigestAlgorithm)} instead. Standard JWA algorithms - * are represented as instances of this new interface in the {@link Jwts.SIG} + * are represented as instances of this new interface in the {@link Jws.alg} * algorithm registry.

    * *

    Signs the constructed JWT with the specified key using the specified algorithm, producing a JWS.

    @@ -841,7 +841,7 @@ public interface JwtBuilder extends ClaimsMutator { /** * Signs the constructed JWT with the specified key using the specified algorithm, producing a JWS. * - *

    The {@link Jwts.SIG} registry makes available all standard signature + *

    The {@link Jws.alg} registry makes available all standard signature * algorithms defined in the JWA specification.

    * *

    It is typically recommended to call the {@link #signWith(Key)} instead for simplicity. @@ -855,7 +855,7 @@ public interface JwtBuilder extends ClaimsMutator { * @throws InvalidKeyException if the Key is insufficient or explicitly disallowed by the JWT specification for * the specified algorithm. * @see #signWith(Key) - * @see Jwts.SIG + * @see Jws.alg * @since 0.12.0 */ JwtBuilder signWith(K key, SecureDigestAlgorithm alg) throws InvalidKeyException; @@ -871,12 +871,12 @@ public interface JwtBuilder extends ClaimsMutator { *

      *
    • If the provided {@code key} is a {@link Password Password} instance, * the {@code KeyAlgorithm} used will be one of the three JWA-standard password-based key algorithms - * ({@link Jwts.KEY#PBES2_HS256_A128KW PBES2_HS256_A128KW}, - * {@link Jwts.KEY#PBES2_HS384_A192KW PBES2_HS384_A192KW}, or - * {@link Jwts.KEY#PBES2_HS512_A256KW PBES2_HS512_A256KW}) as determined by the {@code enc} algorithm's + * ({@link Jwe.enc#PBES2_HS256_A128KW PBES2_HS256_A128KW}, + * {@link Jwe.enc#PBES2_HS384_A192KW PBES2_HS384_A192KW}, or + * {@link Jwe.enc#PBES2_HS512_A256KW PBES2_HS512_A256KW}) as determined by the {@code enc} algorithm's * {@link AeadAlgorithm#getKeyBitLength() key length} requirement.
    • *
    • If the {@code key} is otherwise a standard {@code SecretKey}, the {@code KeyAlgorithm} will be - * {@link Jwts.KEY#DIRECT DIRECT}, indicating that {@code key} should be used directly with the + * {@link Jwe.enc#DIRECT DIRECT}, indicating that {@code key} should be used directly with the * {@code enc} algorithm. In this case, the {@code key} argument MUST be of sufficient strength to * use with the specified {@code enc} algorithm, otherwise an exception will be thrown during encryption. If * desired, secure-random keys suitable for an {@link AeadAlgorithm} may be generated using the algorithm's @@ -885,9 +885,9 @@ public interface JwtBuilder extends ClaimsMutator { * * @param key the symmetric encryption key to use with the {@code enc} algorithm. * @param enc the {@link AeadAlgorithm} algorithm used to encrypt the JWE, usually one of the JWA-standard - * algorithms accessible via {@link Jwts.ENC}. + * algorithms accessible via {@link Jwe.alg}. * @return the JWE builder for method chaining. - * @see Jwts.ENC + * @see Jwe.alg */ JwtBuilder encryptWith(SecretKey key, AeadAlgorithm enc); @@ -908,7 +908,7 @@ public interface JwtBuilder extends ClaimsMutator { * * *

      Most application developers will reference one of the JWA - * {@link Jwts.KEY standard key algorithms} and {@link Jwts.ENC standard encryption algorithms} + * {@link Jwe.enc standard key algorithms} and {@link Jwe.alg standard encryption algorithms} * when invoking this method, but custom implementations are also supported.

      * * @param the type of key that must be used with the specified {@code keyAlg} instance. @@ -917,8 +917,8 @@ public interface JwtBuilder extends ClaimsMutator { * {@code enc} algorithm * @param enc the {@link AeadAlgorithm} algorithm used to encrypt the JWE * @return the JWE builder for method chaining. - * @see Jwts.ENC - * @see Jwts.KEY + * @see Jwe.alg + * @see Jwe.enc */ JwtBuilder encryptWith(K key, KeyAlgorithm keyAlg, AeadAlgorithm enc); diff --git a/api/src/main/java/io/jsonwebtoken/JwtParserBuilder.java b/api/src/main/java/io/jsonwebtoken/JwtParserBuilder.java index 79936695a..c2d967db8 100644 --- a/api/src/main/java/io/jsonwebtoken/JwtParserBuilder.java +++ b/api/src/main/java/io/jsonwebtoken/JwtParserBuilder.java @@ -61,7 +61,7 @@ public interface JwtParserBuilder extends Builder { * @return the builder for method chaining. * @see Unsecured JWS Security Considerations * @see Using the Algorithm "none" - * @see Jwts.SIG#NONE + * @see Jws.alg#NONE * @see #unsecuredDecompression() * @since 0.12.0 */ @@ -90,7 +90,7 @@ public interface JwtParserBuilder extends Builder { * @see Unsecured JWS Security Considerations * @see In the * Compression Hornet’s Nest: A Security Study of Data Compression in Network Services - * @see Jwts.SIG#NONE + * @see Jws.alg#NONE * @see #unsecured() * @since 0.12.0 */ @@ -574,7 +574,7 @@ public interface JwtParserBuilder extends Builder { * *

      Standard Algorithms and Overrides

      * - *

      All JWA-standard AEAD encryption algorithms in the {@link Jwts.ENC} registry are supported by default and + *

      All JWA-standard AEAD encryption algorithms in the {@link Jwe.alg} registry are supported by default and * do not need to be added. The collection may be useful however for removing some algorithms (for example, * any algorithms not used by the application, or those not compatible with application security requirements), * or for adding custom implementations.

      @@ -595,7 +595,7 @@ public interface JwtParserBuilder extends Builder { * * @return the {@link NestedCollection} to use to configure the AEAD encryption algorithms available when parsing. * @see JwtBuilder#encryptWith(Key, KeyAlgorithm, AeadAlgorithm) - * @see Jwts.ENC + * @see Jwe.alg * @see "enc" (Encryption Algorithm) Header Parameter * @see Encryption Algorithm Name (id) requirements * @since 0.12.0 @@ -614,7 +614,7 @@ public interface JwtParserBuilder extends Builder { * *

      Standard Algorithms and Overrides

      * - *

      All JWA-standard key encryption algorithms in the {@link Jwts.KEY} registry are supported by default and + *

      All JWA-standard key encryption algorithms in the {@link Jwe.enc} registry are supported by default and * do not need to be added. The collection may be useful however for removing some algorithms (for example, * any algorithms not used by the application, or those not compatible with application security requirements), * or for adding custom implementations.

      @@ -635,7 +635,7 @@ public interface JwtParserBuilder extends Builder { * * @return the {@link NestedCollection} to use to configure the key algorithms available when parsing. * @see JwtBuilder#encryptWith(Key, KeyAlgorithm, AeadAlgorithm) - * @see Jwts.KEY + * @see Jwe.enc * @see JWE "alg" (Algorithm) Header Parameter * @see Key Algorithm Name (id) requirements * @since 0.12.0 @@ -656,7 +656,7 @@ public interface JwtParserBuilder extends Builder { * *

      Standard Algorithms and Overrides

      * - *

      All JWA-standard signature and MAC algorithms in the {@link Jwts.SIG} registry are supported by default and + *

      All JWA-standard signature and MAC algorithms in the {@link Jws.alg} registry are supported by default and * do not need to be added. The collection may be useful however for removing some algorithms (for example, * any algorithms not used by the application, or those not compatible with application security requirements), or * for adding custom implementations.

      @@ -677,7 +677,7 @@ public interface JwtParserBuilder extends Builder { * * @return the {@link NestedCollection} to use to configure the signature and MAC algorithms available when parsing. * @see JwtBuilder#signWith(Key, SecureDigestAlgorithm) - * @see Jwts.SIG + * @see Jws.alg * @see JWS "alg" (Algorithm) Header Parameter * @see Algorithm Name (id) requirements * @since 0.12.0 diff --git a/api/src/main/java/io/jsonwebtoken/Jwts.java b/api/src/main/java/io/jsonwebtoken/Jwts.java index 5d87653be..bd88366d6 100644 --- a/api/src/main/java/io/jsonwebtoken/Jwts.java +++ b/api/src/main/java/io/jsonwebtoken/Jwts.java @@ -57,7 +57,7 @@ public final class Jwts { // do not change this visibility. Raw type method signature not be publicly exposed: @SuppressWarnings("unchecked") - private static T get(Registry registry, String id) { + static T get(Registry registry, String id) { return (T) registry.forKey(id); } @@ -70,18 +70,17 @@ private static T get(Registry registry, String id) { *
            * Jwts.builder()
            *    // ... etc ...
      -     *    .encryptWith(aKey, Jwts.ENC.A256GCM) // or A128GCM, A192GCM, etc...
      +     *    .encryptWith(aKey, Jwe.alg.A256GCM) // or A128GCM, A192GCM, etc...
            *    .build();
      - *

      They are also available together as a {@link Registry} instance via the {@link #get()} method.

      + *

      They are also available together as a {@link Registry} instance via {@link Jwe.alg#registry()}.

      * - * @see #get() + * @see Jwe.alg#registry() * @since 0.12.0 + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jwe.alg}. */ + @Deprecated public static final class ENC { - private static final String IMPL_CLASSNAME = "io.jsonwebtoken.impl.security.StandardEncryptionAlgorithms"; - private static final Registry REGISTRY = Classes.newInstance(IMPL_CLASSNAME); - /** * Returns all standard JWA Cryptographic * Algorithms for Content Encryption defined in the @@ -89,9 +88,11 @@ public static final class ENC { * Algorithms Registry. * * @return all standard JWA content encryption algorithms. + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jwe.alg#registry()}. */ + @Deprecated public static Registry get() { - return REGISTRY; + return Jwe.alg.registry(); } // prevent instantiation @@ -102,43 +103,61 @@ private ENC() { * {@code AES_128_CBC_HMAC_SHA_256} authenticated encryption algorithm as defined by * RFC 7518, Section 5.2.3. This algorithm * requires a 256-bit (32 byte) key. + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jwe.alg#A128CBC_HS256}. */ - public static final AeadAlgorithm A128CBC_HS256 = get().forKey("A128CBC-HS256"); + @Deprecated + public static final AeadAlgorithm A128CBC_HS256 = Jwe.alg.A128CBC_HS256; /** * {@code AES_192_CBC_HMAC_SHA_384} authenticated encryption algorithm, as defined by * RFC 7518, Section 5.2.4. This algorithm * requires a 384-bit (48 byte) key. + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jwe.alg#A192CBC_HS384}. */ - public static final AeadAlgorithm A192CBC_HS384 = get().forKey("A192CBC-HS384"); + @Deprecated + public static final AeadAlgorithm A192CBC_HS384 = Jwe.alg.A192CBC_HS384; /** * {@code AES_256_CBC_HMAC_SHA_512} authenticated encryption algorithm, as defined by * RFC 7518, Section 5.2.5. This algorithm * requires a 512-bit (64 byte) key. + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jwe.alg#A256CBC_HS512}. */ - public static final AeadAlgorithm A256CBC_HS512 = get().forKey("A256CBC-HS512"); + @Deprecated + public static final AeadAlgorithm A256CBC_HS512 = Jwe.alg.A256CBC_HS512; /** * "AES GCM using 128-bit key" as defined by * RFC 7518, Section 5.3. This * algorithm requires a 128-bit (16 byte) key. + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jwe.alg#A128GCM}. */ - public static final AeadAlgorithm A128GCM = get().forKey("A128GCM"); + @Deprecated + public static final AeadAlgorithm A128GCM = Jwe.alg.A128GCM; /** * "AES GCM using 192-bit key" as defined by * RFC 7518, Section 5.3. This * algorithm requires a 192-bit (24 byte) key. + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jwe.alg#A192GCM}. */ - public static final AeadAlgorithm A192GCM = get().forKey("A192GCM"); + @Deprecated + public static final AeadAlgorithm A192GCM = Jwe.alg.A192GCM; /** * "AES GCM using 256-bit key" as defined by * RFC 7518, Section 5.3. This * algorithm requires a 256-bit (32 byte) key. + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jwe.alg#A256GCM}. */ - public static final AeadAlgorithm A256GCM = get().forKey("A256GCM"); + @Deprecated + public static final AeadAlgorithm A256GCM = Jwe.alg.A256GCM; } /** @@ -150,18 +169,17 @@ private ENC() { *
            * Jwts.builder()
            *    // ... etc ...
      -     *    .signWith(aKey, Jwts.SIG.HS512) // or RS512, PS256, EdDSA, etc...
      +     *    .signWith(aKey, Jws.alg.HS512) // or RS512, PS256, EdDSA, etc...
            *    .build();
      *

      They are also available together as a {@link Registry} instance via the {@link #get()} method.

      * * @see #get() * @since 0.12.0 + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jws.alg}. */ + @Deprecated public static final class SIG { - private static final String IMPL_CLASSNAME = "io.jsonwebtoken.impl.security.StandardSecureDigestAlgorithms"; - private static final Registry> REGISTRY = Classes.newInstance(IMPL_CLASSNAME); - //prevent instantiation private SIG() { } @@ -173,9 +191,11 @@ private SIG() { * Algorithms Registry. * * @return all standard JWA digital signature and MAC algorithms. + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jws.alg#registry()} */ + @Deprecated public static Registry> get() { - return REGISTRY; + return Jws.alg.registry(); } /** @@ -183,50 +203,71 @@ private SIG() { * RFC 7518, Section 3.6. This algorithm * is used only when creating unsecured (not integrity protected) JWSs and is not usable in any other scenario. * Any attempt to call its methods will result in an exception being thrown. + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jws.alg#NONE} */ - public static final SecureDigestAlgorithm NONE = Jwts.get(REGISTRY, "none"); + @Deprecated + public static final SecureDigestAlgorithm NONE = Jws.alg.NONE; /** * {@code HMAC using SHA-256} message authentication algorithm as defined by * RFC 7518, Section 3.2. This algorithm * requires a 256-bit (32 byte) key. + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jws.alg#HS256} */ - public static final MacAlgorithm HS256 = Jwts.get(REGISTRY, "HS256"); + @Deprecated + public static final MacAlgorithm HS256 = Jws.alg.HS256; /** * {@code HMAC using SHA-384} message authentication algorithm as defined by * RFC 7518, Section 3.2. This algorithm * requires a 384-bit (48 byte) key. + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jws.alg#HS384} */ - public static final MacAlgorithm HS384 = Jwts.get(REGISTRY, "HS384"); + @Deprecated + public static final MacAlgorithm HS384 = Jws.alg.HS384; /** * {@code HMAC using SHA-512} message authentication algorithm as defined by * RFC 7518, Section 3.2. This algorithm * requires a 512-bit (64 byte) key. + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jws.alg#HS512} */ - public static final MacAlgorithm HS512 = Jwts.get(REGISTRY, "HS512"); + @Deprecated + public static final MacAlgorithm HS512 = Jws.alg.HS512; /** * {@code RSASSA-PKCS1-v1_5 using SHA-256} signature algorithm as defined by * RFC 7518, Section 3.3. This algorithm * requires a 2048-bit key. + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jws.alg#RS256} */ - public static final SignatureAlgorithm RS256 = Jwts.get(REGISTRY, "RS256"); + @Deprecated + public static final SignatureAlgorithm RS256 = Jws.alg.RS256; /** * {@code RSASSA-PKCS1-v1_5 using SHA-384} signature algorithm as defined by * RFC 7518, Section 3.3. This algorithm * requires a 2048-bit key, but the JJWT team recommends a 3072-bit key. + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jws.alg#RS384} */ - public static final SignatureAlgorithm RS384 = Jwts.get(REGISTRY, "RS384"); + @Deprecated + public static final SignatureAlgorithm RS384 = Jws.alg.RS384; /** * {@code RSASSA-PKCS1-v1_5 using SHA-512} signature algorithm as defined by * RFC 7518, Section 3.3. This algorithm * requires a 2048-bit key, but the JJWT team recommends a 4096-bit key. + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jws.alg#RS512} */ - public static final SignatureAlgorithm RS512 = Jwts.get(REGISTRY, "RS512"); + @Deprecated + public static final SignatureAlgorithm RS512 = Jws.alg.RS512; /** * {@code RSASSA-PSS using SHA-256 and MGF1 with SHA-256} signature algorithm as defined by @@ -236,8 +277,11 @@ private SIG() { *

      1 Requires Java 11 or a compatible JCA Provider (like BouncyCastle) in the runtime * classpath. If on Java 10 or earlier, BouncyCastle will be used automatically if found in the runtime * classpath.

      + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jws.alg#PS256} */ - public static final SignatureAlgorithm PS256 = Jwts.get(REGISTRY, "PS256"); + @Deprecated + public static final SignatureAlgorithm PS256 = Jws.alg.PS256; /** * {@code RSASSA-PSS using SHA-384 and MGF1 with SHA-384} signature algorithm as defined by @@ -247,8 +291,11 @@ private SIG() { *

      1 Requires Java 11 or a compatible JCA Provider (like BouncyCastle) in the runtime * classpath. If on Java 10 or earlier, BouncyCastle will be used automatically if found in the runtime * classpath.

      + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jws.alg#PS384} */ - public static final SignatureAlgorithm PS384 = Jwts.get(REGISTRY, "PS384"); + @Deprecated + public static final SignatureAlgorithm PS384 = Jws.alg.PS384; /** * {@code RSASSA-PSS using SHA-512 and MGF1 with SHA-512} signature algorithm as defined by @@ -258,29 +305,41 @@ private SIG() { *

      1 Requires Java 11 or a compatible JCA Provider (like BouncyCastle) in the runtime * classpath. If on Java 10 or earlier, BouncyCastle will be used automatically if found in the runtime * classpath.

      + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jws.alg#PS512} */ - public static final SignatureAlgorithm PS512 = Jwts.get(REGISTRY, "PS512"); + @Deprecated + public static final SignatureAlgorithm PS512 = Jws.alg.PS512; /** * {@code ECDSA using P-256 and SHA-256} signature algorithm as defined by * RFC 7518, Section 3.4. This algorithm * requires a 256-bit key. + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jws.alg#ES256} */ - public static final SignatureAlgorithm ES256 = Jwts.get(REGISTRY, "ES256"); + @Deprecated + public static final SignatureAlgorithm ES256 = Jws.alg.ES256; /** * {@code ECDSA using P-384 and SHA-384} signature algorithm as defined by * RFC 7518, Section 3.4. This algorithm * requires a 384-bit key. + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jws.alg#ES384} */ - public static final SignatureAlgorithm ES384 = Jwts.get(REGISTRY, "ES384"); + @Deprecated + public static final SignatureAlgorithm ES384 = Jws.alg.ES384; /** * {@code ECDSA using P-521 and SHA-512} signature algorithm as defined by * RFC 7518, Section 3.4. This algorithm * requires a 521-bit key. + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jws.alg#ES512} */ - public static final SignatureAlgorithm ES512 = Jwts.get(REGISTRY, "ES512"); + @Deprecated + public static final SignatureAlgorithm ES512 = Jws.alg.ES512; /** * {@code EdDSA} signature algorithm defined by @@ -300,8 +359,11 @@ private SIG() { * *

      1This algorithm requires at least JDK 15 or a compatible JCA Provider (like BouncyCastle) in the runtime * classpath.

      + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jws.alg#EdDSA} */ - public static final SignatureAlgorithm EdDSA = Jwts.get(REGISTRY, "EdDSA"); + @Deprecated + public static final SignatureAlgorithm EdDSA = Jws.alg.EdDSA; } /** @@ -311,34 +373,38 @@ private SIG() { *
            * Jwts.builder()
            *    // ... etc ...
      -     *    .encryptWith(aKey, Jwts.KEY.ECDH_ES_A256KW, Jwts.ENC.A256GCM)
      +     *    .encryptWith(aKey, Jwe.enc.ECDH_ES_A256KW, Jwe.alg.A256GCM)
            *    .build();
      - *

      They are also available together as a {@link Registry} instance via the {@link #get()} method.

      + *

      They are also available together as a {@link Registry} instance via the {@link Jwe.enc#registry()} method.

      * - * @see #get() + * @see Jwe.enc#registry() * @since 0.12.0 + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jwe.enc}. */ + @Deprecated public static final class KEY { - private static final String IMPL_CLASSNAME = "io.jsonwebtoken.impl.security.StandardKeyAlgorithms"; - private static final Registry> REGISTRY = Classes.newInstance(IMPL_CLASSNAME); - /** * Returns all standard JWA standard Cryptographic * Algorithms for Key Management.. * * @return all standard JWA Key Management algorithms. + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jwe.enc#registry()} */ + @Deprecated public static Registry> get() { - return REGISTRY; + return Jwe.enc.registry(); } /** * Key algorithm reflecting direct use of a shared symmetric key as the JWE AEAD encryption key, as defined * by RFC 7518 (JWA), Section 4.5. This * algorithm does not produce encrypted key ciphertext. + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jwe.enc#DIRECT} */ - public static final KeyAlgorithm DIRECT = Jwts.get(REGISTRY, "dir"); + @Deprecated + public static final KeyAlgorithm DIRECT = Jwe.enc.DIRECT; /** * AES Key Wrap algorithm with default initial value using a 128-bit key, as defined by @@ -361,8 +427,11 @@ public static final class KEY { *
    • Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
    • * + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jwe.enc#A128KW} */ - public static final SecretKeyAlgorithm A128KW = Jwts.get(REGISTRY, "A128KW"); + @Deprecated + public static final SecretKeyAlgorithm A128KW = Jwe.enc.A128KW; /** * AES Key Wrap algorithm with default initial value using a 192-bit key, as defined by @@ -385,8 +454,11 @@ public static final class KEY { *
    • Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
    • * + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jwe.enc#A192KW} */ - public static final SecretKeyAlgorithm A192KW = Jwts.get(REGISTRY, "A192KW"); + @Deprecated + public static final SecretKeyAlgorithm A192KW = Jwe.enc.A192KW; /** * AES Key Wrap algorithm with default initial value using a 256-bit key, as defined by @@ -409,8 +481,11 @@ public static final class KEY { *
    • Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
    • * + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jwe.enc#A256KW} */ - public static final SecretKeyAlgorithm A256KW = Jwts.get(REGISTRY, "A256KW"); + @Deprecated + public static final SecretKeyAlgorithm A256KW = Jwe.enc.A256KW; /** * Key wrap algorithm with AES GCM using a 128-bit key, as defined by @@ -448,8 +523,11 @@ public static final class KEY { *
    • Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
    • * + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jwe.enc#A128GCMKW} */ - public static final SecretKeyAlgorithm A128GCMKW = Jwts.get(REGISTRY, "A128GCMKW"); + @Deprecated + public static final SecretKeyAlgorithm A128GCMKW = Jwe.enc.A128GCMKW; /** * Key wrap algorithm with AES GCM using a 192-bit key, as defined by @@ -487,8 +565,11 @@ public static final class KEY { *
    • Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
    • * + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jwe.enc#A192GCMKW} */ - public static final SecretKeyAlgorithm A192GCMKW = Jwts.get(REGISTRY, "A192GCMKW"); + @Deprecated + public static final SecretKeyAlgorithm A192GCMKW = Jwe.enc.A192GCMKW; /** * Key wrap algorithm with AES GCM using a 256-bit key, as defined by @@ -526,8 +607,11 @@ public static final class KEY { *
    • Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
    • * + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jwe.enc#A256GCMKW} */ - public static final SecretKeyAlgorithm A256GCMKW = Jwts.get(REGISTRY, "A256GCMKW"); + @Deprecated + public static final SecretKeyAlgorithm A256GCMKW = Jwe.enc.A256GCMKW; /** * Key encryption algorithm using PBES2 with HMAC SHA-256 and "A128KW" wrapping @@ -571,8 +655,11 @@ public static final class KEY { *
    • Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
    • * + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jwe.enc#PBES2_HS256_A128KW} */ - public static final KeyAlgorithm PBES2_HS256_A128KW = Jwts.get(REGISTRY, "PBES2-HS256+A128KW"); + @Deprecated + public static final KeyAlgorithm PBES2_HS256_A128KW = Jwe.enc.PBES2_HS256_A128KW; /** * Key encryption algorithm using PBES2 with HMAC SHA-384 and "A192KW" wrapping @@ -616,8 +703,11 @@ public static final class KEY { *
    • Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
    • * + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jwe.enc#PBES2_HS384_A192KW} */ - public static final KeyAlgorithm PBES2_HS384_A192KW = Jwts.get(REGISTRY, "PBES2-HS384+A192KW"); + @Deprecated + public static final KeyAlgorithm PBES2_HS384_A192KW = Jwe.enc.PBES2_HS384_A192KW; /** * Key encryption algorithm using PBES2 with HMAC SHA-512 and "A256KW" wrapping @@ -661,8 +751,11 @@ public static final class KEY { *
    • Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
    • * + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jwe.enc#PBES2_HS512_A256KW} */ - public static final KeyAlgorithm PBES2_HS512_A256KW = Jwts.get(REGISTRY, "PBES2-HS512+A256KW"); + @Deprecated + public static final KeyAlgorithm PBES2_HS512_A256KW = Jwe.enc.PBES2_HS512_A256KW; /** * Key Encryption with {@code RSAES-PKCS1-v1_5}, as defined by @@ -686,8 +779,11 @@ public static final class KEY { *
    • Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
    • * + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jwe.enc#RSA1_5} */ - public static final KeyAlgorithm RSA1_5 = Jwts.get(REGISTRY, "RSA1_5"); + @Deprecated + public static final KeyAlgorithm RSA1_5 = Jwe.enc.RSA1_5; /** * Key Encryption with {@code RSAES OAEP using default parameters}, as defined by @@ -711,8 +807,11 @@ public static final class KEY { *
    • Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
    • * + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jwe.enc#RSA_OAEP} */ - public static final KeyAlgorithm RSA_OAEP = Jwts.get(REGISTRY, "RSA-OAEP"); + @Deprecated + public static final KeyAlgorithm RSA_OAEP = Jwe.enc.RSA_OAEP; /** * Key Encryption with {@code RSAES OAEP using SHA-256 and MGF1 with SHA-256}, as defined by @@ -736,8 +835,11 @@ public static final class KEY { *
    • Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
    • * + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jwe.enc#RSA_OAEP_256} */ - public static final KeyAlgorithm RSA_OAEP_256 = Jwts.get(REGISTRY, "RSA-OAEP-256"); + @Deprecated + public static final KeyAlgorithm RSA_OAEP_256 = Jwe.enc.RSA_OAEP_256; /** * Key Agreement with {@code ECDH-ES using Concat KDF} as defined by @@ -777,8 +879,11 @@ public static final class KEY { *
    • Returns the derived symmetric {@code SecretKey} for JJWT to use to decrypt the entire * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
    • * + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jwe.enc#ECDH_ES} */ - public static final KeyAlgorithm ECDH_ES = Jwts.get(REGISTRY, "ECDH-ES"); + @Deprecated + public static final KeyAlgorithm ECDH_ES = Jwe.enc.ECDH_ES; /** * Key Agreement with Key Wrapping via @@ -825,8 +930,11 @@ public static final class KEY { *
    • Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
    • * + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jwe.enc#ECDH_ES_A128KW} */ - public static final KeyAlgorithm ECDH_ES_A128KW = Jwts.get(REGISTRY, "ECDH-ES+A128KW"); + @Deprecated + public static final KeyAlgorithm ECDH_ES_A128KW = Jwe.enc.ECDH_ES_A128KW; /** * Key Agreement with Key Wrapping via @@ -874,8 +982,11 @@ public static final class KEY { *
    • Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
    • * + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jwe.enc#ECDH_ES_A192KW} */ - public static final KeyAlgorithm ECDH_ES_A192KW = Jwts.get(REGISTRY, "ECDH-ES+A192KW"); + @Deprecated + public static final KeyAlgorithm ECDH_ES_A192KW = Jwe.enc.ECDH_ES_A192KW; /** * Key Agreement with Key Wrapping via @@ -923,8 +1034,11 @@ public static final class KEY { *
    • Returns the decryption key plaintext as a {@link SecretKey} for JJWT to use to decrypt the entire * JWE using the JWE's identified "enc" {@link AeadAlgorithm}.
    • * + * + * @deprecated since JJWT_RELEASE_VERSION in favor of {@link Jwe.enc#ECDH_ES_A256KW} */ - public static final KeyAlgorithm ECDH_ES_A256KW = Jwts.get(REGISTRY, "ECDH-ES+A256KW"); + @Deprecated + public static final KeyAlgorithm ECDH_ES_A256KW = Jwe.enc.ECDH_ES_A256KW; //prevent instantiation private KEY() { diff --git a/api/src/main/java/io/jsonwebtoken/SignatureAlgorithm.java b/api/src/main/java/io/jsonwebtoken/SignatureAlgorithm.java index ee25883d7..a80998eef 100644 --- a/api/src/main/java/io/jsonwebtoken/SignatureAlgorithm.java +++ b/api/src/main/java/io/jsonwebtoken/SignatureAlgorithm.java @@ -34,7 +34,7 @@ * JSON Web Algorithms specification. * * @since 0.1 - * @deprecated since 0.12.0; use {@link Jwts.SIG} instead. + * @deprecated since 0.12.0; use {@link Jws.alg} instead. */ @Deprecated public enum SignatureAlgorithm { diff --git a/api/src/main/java/io/jsonwebtoken/security/AeadAlgorithm.java b/api/src/main/java/io/jsonwebtoken/security/AeadAlgorithm.java index 7e82d85f9..291ca97c9 100644 --- a/api/src/main/java/io/jsonwebtoken/security/AeadAlgorithm.java +++ b/api/src/main/java/io/jsonwebtoken/security/AeadAlgorithm.java @@ -16,7 +16,6 @@ package io.jsonwebtoken.security; import io.jsonwebtoken.Identifiable; -import io.jsonwebtoken.Jwts; import javax.crypto.SecretKey; import java.io.OutputStream; @@ -27,7 +26,7 @@ * Per JWE RFC 7516, Section 4.1.2, all JWEs * MUST use an AEAD algorithm to encrypt or decrypt the JWE payload/content. Consequently, all * JWA "enc" algorithms are AEAD - * algorithms, and they are accessible as concrete instances via {@link Jwts.ENC}. + * algorithms, and they are accessible as concrete instances via {@link io.jsonwebtoken.Jwe.alg Jwe.alg}. * *

      "enc" identifier

      * @@ -58,7 +57,7 @@ *

      The resulting {@code key} is guaranteed to have the correct algorithm parameters and strength/length necessary for * that exact {@code aeadAlgorithm} instance.

      * - * @see Jwts.ENC + * @see io.jsonwebtoken.Jwe.alg Jwe.alg * @see Identifiable#getId() * @see KeyLengthSupplier * @see KeyBuilderSupplier diff --git a/api/src/main/java/io/jsonwebtoken/security/DigestAlgorithm.java b/api/src/main/java/io/jsonwebtoken/security/DigestAlgorithm.java index daeaa6a7a..724e0812b 100644 --- a/api/src/main/java/io/jsonwebtoken/security/DigestAlgorithm.java +++ b/api/src/main/java/io/jsonwebtoken/security/DigestAlgorithm.java @@ -46,13 +46,13 @@ * * * {@link MacAlgorithm} - * {@link io.jsonwebtoken.Jwts.SIG Jwts.SIG} + * {@link io.jsonwebtoken.Jws.alg Jws.alg} * Requires a {@link SecretKey} to both compute and verify digests (aka * "Message Authentication Codes"). * * * {@link SignatureAlgorithm} - * {@link io.jsonwebtoken.Jwts.SIG Jwts.SIG} + * {@link io.jsonwebtoken.Jws.alg Jws.alg} * Requires a {@link PrivateKey} to compute and {@link PublicKey} to verify digests * (aka "Digital Signatures"). * @@ -73,7 +73,7 @@ * @param the type of {@link Request} used when computing a digest. * @param the type of {@link VerifyDigestRequest} used when verifying a digest. * @see Jwks.HASH - * @see io.jsonwebtoken.Jwts.SIG Jwts.SIG + * @see io.jsonwebtoken.Jws.alg Jws.alg * @since 0.12.0 */ public interface DigestAlgorithm, V extends VerifyDigestRequest> extends Identifiable { diff --git a/api/src/main/java/io/jsonwebtoken/security/KeyAlgorithm.java b/api/src/main/java/io/jsonwebtoken/security/KeyAlgorithm.java index e3cd13c65..d2873e6ac 100644 --- a/api/src/main/java/io/jsonwebtoken/security/KeyAlgorithm.java +++ b/api/src/main/java/io/jsonwebtoken/security/KeyAlgorithm.java @@ -16,7 +16,6 @@ package io.jsonwebtoken.security; import io.jsonwebtoken.Identifiable; -import io.jsonwebtoken.Jwts; import javax.crypto.SecretKey; import java.security.Key; @@ -30,7 +29,7 @@ * *

      All standard Key Algorithms are defined in * JWA (RFC 7518), Section 4.1, - * and they are all available as concrete instances via {@link Jwts.KEY}.

      + * and they are all available as concrete instances via {@link io.jsonwebtoken.Jwe.enc Jwe.enc}.

      * *

      "alg" identifier

      * @@ -40,7 +39,7 @@ * * @param The type of key to use to obtain the AEAD encryption key * @param The type of key to use to obtain the AEAD decryption key - * @see Jwts.KEY + * @see io.jsonwebtoken.Jwe.enc Jwe.enc * @see RFC 7561, Section 2: JWE Key (Management) Algorithms * @since 0.12.0 */ diff --git a/api/src/main/java/io/jsonwebtoken/security/Keys.java b/api/src/main/java/io/jsonwebtoken/security/Keys.java index 9ae54e73e..1a43323c6 100644 --- a/api/src/main/java/io/jsonwebtoken/security/Keys.java +++ b/api/src/main/java/io/jsonwebtoken/security/Keys.java @@ -15,7 +15,7 @@ */ package io.jsonwebtoken.security; -import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.Jws; import io.jsonwebtoken.lang.Assert; import io.jsonwebtoken.lang.Classes; @@ -77,7 +77,7 @@ public static SecretKey hmacShaKeyFor(byte[] bytes) throws WeakKeyException { "is not secure enough for any JWT HMAC-SHA algorithm. The JWT " + "JWA Specification (RFC 7518, Section 3.2) states that keys used with HMAC-SHA algorithms MUST have a " + "size >= 256 bits (the key size must be greater than or equal to the hash " + - "output size). Consider using the Jwts.SIG.HS256.key() builder (or HS384.key() " + + "output size). Consider using the Jws.alg.HS256.key() builder (or HS384.key() " + "or HS512.key()) to create a key guaranteed to be secure enough for your preferred HMAC-SHA " + "algorithm. See https://tools.ietf.org/html/rfc7518#section-3.2 for more information."; throw new WeakKeyException(msg); @@ -90,9 +90,9 @@ public static SecretKey hmacShaKeyFor(byte[] bytes) throws WeakKeyException { * length for that specific algorithm by calling their {@code key()} builder method directly. For example:

      * *
      
      -     * {@link Jwts.SIG#HS256}.key().build();
      -     * {@link Jwts.SIG#HS384}.key().build();
      -     * {@link Jwts.SIG#HS512}.key().build();
      +     * {@link Jws.alg#HS256}.key().build();
      +     * {@link Jws.alg#HS384}.key().build();
      +     * {@link Jws.alg#HS512}.key().build();
            * 
      * *

      Call those methods as needed instead of this static {@code secretKeyFor} helper method - the returned @@ -139,7 +139,7 @@ public static SecretKey hmacShaKeyFor(byte[] bytes) throws WeakKeyException { @Deprecated public static SecretKey secretKeyFor(io.jsonwebtoken.SignatureAlgorithm alg) throws IllegalArgumentException { Assert.notNull(alg, "SignatureAlgorithm cannot be null."); - SecureDigestAlgorithm salg = Jwts.SIG.get().get(alg.name()); + SecureDigestAlgorithm salg = Jws.alg.registry().get(alg.name()); if (!(salg instanceof MacAlgorithm)) { String msg = "The " + alg.name() + " algorithm does not support shared secret keys."; throw new IllegalArgumentException(msg); @@ -154,11 +154,11 @@ public static SecretKey secretKeyFor(io.jsonwebtoken.SignatureAlgorithm alg) thr * for that specific algorithm by calling their {@code keyPair()} builder method directly. For example:

      * *
      -     * Jwts.SIG.{@link Jwts.SIG#RS256 RS256}.keyPair().build();
      -     * Jwts.SIG.{@link Jwts.SIG#RS384 RS384}.keyPair().build();
      -     * Jwts.SIG.{@link Jwts.SIG#RS512 RS512}.keyPair().build();
      +     * Jws.alg.{@link Jws.alg#RS256 RS256}.keyPair().build();
      +     * Jws.alg.{@link Jws.alg#RS384 RS384}.keyPair().build();
      +     * Jws.alg.{@link Jws.alg#RS512 RS512}.keyPair().build();
            * ... etc ...
      -     * Jwts.SIG.{@link Jwts.SIG#ES512 ES512}.keyPair().build();
      + * Jws.alg.{@link Jws.alg#ES512 ES512}.keyPair().build(); * *

      Call those methods as needed instead of this static {@code keyPairFor} helper method - the returned * {@link KeyPairBuilder} allows callers to specify a preferred Provider or SecureRandom on the builder if @@ -244,7 +244,7 @@ public static SecretKey secretKeyFor(io.jsonwebtoken.SignatureAlgorithm alg) thr @Deprecated public static KeyPair keyPairFor(io.jsonwebtoken.SignatureAlgorithm alg) throws IllegalArgumentException { Assert.notNull(alg, "SignatureAlgorithm cannot be null."); - SecureDigestAlgorithm salg = Jwts.SIG.get().get(alg.name()); + SecureDigestAlgorithm salg = Jws.alg.registry().get(alg.name()); if (!(salg instanceof SignatureAlgorithm)) { String msg = "The " + alg.name() + " algorithm does not support Key Pairs."; throw new IllegalArgumentException(msg); diff --git a/api/src/main/java/io/jsonwebtoken/security/MacAlgorithm.java b/api/src/main/java/io/jsonwebtoken/security/MacAlgorithm.java index e34d927b3..21b552fe2 100644 --- a/api/src/main/java/io/jsonwebtoken/security/MacAlgorithm.java +++ b/api/src/main/java/io/jsonwebtoken/security/MacAlgorithm.java @@ -55,9 +55,9 @@ *

      JWA Standard Implementations

      * *

      Constant definitions and utility methods for all JWA (RFC 7518) standard MAC algorithms are - * available via {@link io.jsonwebtoken.Jwts.SIG Jwts.SIG}.

      + * available via {@link io.jsonwebtoken.Jws.alg Jws.alg}.

      * - * @see io.jsonwebtoken.Jwts.SIG Jwts.SIG + * @see io.jsonwebtoken.Jws.alg Jws.alg * @since 0.12.0 */ public interface MacAlgorithm extends SecureDigestAlgorithm, diff --git a/api/src/main/java/io/jsonwebtoken/security/SecureDigestAlgorithm.java b/api/src/main/java/io/jsonwebtoken/security/SecureDigestAlgorithm.java index ccac48a2e..a3cc69a56 100644 --- a/api/src/main/java/io/jsonwebtoken/security/SecureDigestAlgorithm.java +++ b/api/src/main/java/io/jsonwebtoken/security/SecureDigestAlgorithm.java @@ -37,7 +37,7 @@ * *

      Constant definitions and utility methods for all JWA (RFC 7518) standard * Cryptographic Algorithms for Digital Signatures and - * MACs are available via {@link io.jsonwebtoken.Jwts.SIG Jwts.SIG}.

      + * MACs are available via {@link io.jsonwebtoken.Jws.alg Jws.alg}.

      * *

      "alg" identifier

      * diff --git a/api/src/main/java/io/jsonwebtoken/security/SignatureAlgorithm.java b/api/src/main/java/io/jsonwebtoken/security/SignatureAlgorithm.java index 2df975ff3..e26f4de34 100644 --- a/api/src/main/java/io/jsonwebtoken/security/SignatureAlgorithm.java +++ b/api/src/main/java/io/jsonwebtoken/security/SignatureAlgorithm.java @@ -46,9 +46,9 @@ *

      JWA Standard Implementations

      * *

      Constant definitions and utility methods for all JWA (RFC 7518) standard signature algorithms are - * available via {@link io.jsonwebtoken.Jwts.SIG Jwts.SIG}.

      + * available via {@link io.jsonwebtoken.Jws.alg Jws.alg}.

      * - * @see io.jsonwebtoken.Jwts.SIG Jwts.SIG + * @see io.jsonwebtoken.Jws.alg Jws.alg * @since 0.12.0 */ public interface SignatureAlgorithm extends SecureDigestAlgorithm, KeyPairBuilderSupplier { diff --git a/impl/src/main/java/io/jsonwebtoken/impl/DefaultJweHeader.java b/impl/src/main/java/io/jsonwebtoken/impl/DefaultJweHeader.java index bd6ff517c..337d68842 100644 --- a/impl/src/main/java/io/jsonwebtoken/impl/DefaultJweHeader.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/DefaultJweHeader.java @@ -16,7 +16,7 @@ package io.jsonwebtoken.impl; import io.jsonwebtoken.JweHeader; -import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.Jws; import io.jsonwebtoken.impl.lang.Converters; import io.jsonwebtoken.impl.lang.Parameter; import io.jsonwebtoken.impl.lang.Parameters; @@ -63,7 +63,7 @@ public class DefaultJweHeader extends DefaultProtectedHeader implements JweHeade static boolean isCandidate(ParameterMap map) { String id = map.get(DefaultHeader.ALGORITHM); - return Strings.hasText(id) && !id.equalsIgnoreCase(Jwts.SIG.NONE.getId()) && // alg cannot be empty or 'none' + return Strings.hasText(id) && !id.equalsIgnoreCase(Jws.alg.NONE.getId()) && // alg cannot be empty or 'none' Strings.hasText(map.get(ENCRYPTION_ALGORITHM)); // enc cannot be empty // return Strings.hasText(map.get(ENCRYPTION_ALGORITHM)) || // MUST have at least an `enc` header // !Collections.isEmpty(map.get(EPK)) || diff --git a/impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtBuilder.java b/impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtBuilder.java index de01e466c..220619a27 100644 --- a/impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtBuilder.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtBuilder.java @@ -17,10 +17,11 @@ import io.jsonwebtoken.Claims; import io.jsonwebtoken.Header; +import io.jsonwebtoken.Jwe; import io.jsonwebtoken.JweHeader; +import io.jsonwebtoken.Jws; import io.jsonwebtoken.JwsHeader; import io.jsonwebtoken.JwtBuilder; -import io.jsonwebtoken.Jwts; import io.jsonwebtoken.impl.io.Base64UrlStreamEncoder; import io.jsonwebtoken.impl.io.ByteBase64UrlStreamEncoder; import io.jsonwebtoken.impl.io.CountingInputStream; @@ -90,7 +91,7 @@ public class DefaultJwtBuilder implements JwtBuilder { private Payload payload = Payload.EMPTY; - private SecureDigestAlgorithm sigAlg = Jwts.SIG.NONE; + private SecureDigestAlgorithm sigAlg = Jws.alg.NONE; private Function, byte[]> signFunction; private AeadAlgorithm enc; // MUST be Symmetric AEAD per https://tools.ietf.org/html/rfc7516#section-4.1.2 @@ -228,7 +229,7 @@ public JwtBuilder signWith(K key, final SecureDigestAlgorithm JwtBuilder signWith(K key, final SecureDigestAlgorithm) Jwts.SIG.get().forKey(alg.getValue())); + return signWith(key, (SecureDigestAlgorithm) Jws.alg.registry().forKey(alg.getValue())); } @SuppressWarnings("deprecation") // TODO: remove method for 1.0 @@ -279,7 +280,7 @@ public JwtBuilder encryptWith(SecretKey key, AeadAlgorithm enc) { if (key instanceof Password) { return encryptWith((Password) key, new Pbes2HsAkwAlgorithm(enc.getKeyBitLength()), enc); } - return encryptWith(key, Jwts.KEY.DIRECT, enc); + return encryptWith(key, Jwe.enc.DIRECT, enc); } @Override @@ -635,7 +636,7 @@ private String unprotected(final Payload content) { Assert.stateNotNull(content, "Content argument cannot be null."); assertPayloadEncoding("unprotected JWT"); - this.headerBuilder.add(DefaultHeader.ALGORITHM.getId(), Jwts.SIG.NONE.getId()); + this.headerBuilder.add(DefaultHeader.ALGORITHM.getId(), Jws.alg.NONE.getId()); final ByteArrayOutputStream jwt = new ByteArrayOutputStream(512); diff --git a/impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtParser.java b/impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtParser.java index 7b03ab93c..45b3b34ba 100644 --- a/impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtParser.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtParser.java @@ -125,13 +125,13 @@ public class DefaultJwtParser extends AbstractParser> implements JwtPa "Section 4.1.2. See https://www.rfc-editor.org/rfc/rfc7516.html#section-4.1.2 for more information."; private static final String UNSECURED_DISABLED_MSG_PREFIX = "Unsecured JWSs (those with an " + - DefaultHeader.ALGORITHM + " header value of '" + Jwts.SIG.NONE.getId() + "') are disallowed by " + + DefaultHeader.ALGORITHM + " header value of '" + Jws.alg.NONE.getId() + "') are disallowed by " + "default as mandated by https://www.rfc-editor.org/rfc/rfc7518.html#section-3.6. If you wish to " + "allow them to be parsed, call the JwtParserBuilder.unsecured() method, but please read the " + "security considerations covered in that method's JavaDoc before doing so. Header: "; private static final String CRIT_UNSECURED_MSG = "Unsecured JWSs (those with an " + DefaultHeader.ALGORITHM + - " header value of '" + Jwts.SIG.NONE.getId() + "') may not use the " + DefaultProtectedHeader.CRIT + + " header value of '" + Jws.alg.NONE.getId() + "') may not use the " + DefaultProtectedHeader.CRIT + " header parameter per https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.11 (\"the [crit] Header " + "Parameter MUST be integrity protected; therefore, it MUST occur only within [a] JWS Protected Header)\"." + " Header: %s"; @@ -147,11 +147,11 @@ public class DefaultJwtParser extends AbstractParser> implements JwtPa "is supported by using the JwtParserBuilder.critical method. Header: %s"; private static final String JWE_NONE_MSG = "JWEs do not support key management " + DefaultHeader.ALGORITHM + - " header value '" + Jwts.SIG.NONE.getId() + "' per " + + " header value '" + Jws.alg.NONE.getId() + "' per " + "https://www.rfc-editor.org/rfc/rfc7518.html#section-4.1"; private static final String JWS_NONE_SIG_MISMATCH_MSG = "The JWS header references signature algorithm '" + - Jwts.SIG.NONE.getId() + "' yet the compact JWS string contains a signature. This is not permitted " + + Jws.alg.NONE.getId() + "' yet the compact JWS string contains a signature. This is not permitted " + "per https://tools.ietf.org/html/rfc7518#section-3.6."; private static final String B64_MISSING_PAYLOAD = "Unable to verify JWS signature: the parser has encountered an " + @@ -170,7 +170,7 @@ public class DefaultJwtParser extends AbstractParser> implements JwtPa private static final String UNPROTECTED_DECOMPRESSION_MSG = "The JWT header references compression algorithm " + "'%s', but payload decompression for Unprotected JWTs (those with an " + DefaultHeader.ALGORITHM + - " header value of '" + Jwts.SIG.NONE.getId() + "') or Unencoded JWSs (those with a " + + " header value of '" + Jws.alg.NONE.getId() + "') or Unencoded JWSs (those with a " + DefaultJwsHeader.B64 + " header value of false) that also rely on a SigningKeyResolver are disallowed " + "by default to protect against [Denial of Service attacks](" + "https://www.usenix.org/system/files/conference/usenixsecurity15/sec15-paper-pellegrino.pdf). If you " + @@ -397,7 +397,7 @@ private byte[] verifySignature(final TokenizedJwt tokenized, final JwsHeader jws String msg = tokenized instanceof TokenizedJwe ? MISSING_JWE_ALG_MSG : MISSING_JWS_ALG_MSG; throw new MalformedJwtException(msg); } - final boolean unsecured = Jwts.SIG.NONE.getId().equalsIgnoreCase(alg); + final boolean unsecured = Jws.alg.NONE.getId().equalsIgnoreCase(alg); final CharSequence base64UrlDigest = tokenized.getDigest(); final boolean hasDigest = Strings.hasText(base64UrlDigest); diff --git a/impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtParserBuilder.java b/impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtParserBuilder.java index c12b1054b..ca838345b 100644 --- a/impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtParserBuilder.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtParserBuilder.java @@ -18,6 +18,8 @@ import io.jsonwebtoken.ClaimsBuilder; import io.jsonwebtoken.Clock; import io.jsonwebtoken.CompressionCodecResolver; +import io.jsonwebtoken.Jwe; +import io.jsonwebtoken.Jws; import io.jsonwebtoken.JwtParser; import io.jsonwebtoken.JwtParserBuilder; import io.jsonwebtoken.Jwts; @@ -85,11 +87,11 @@ public class DefaultJwtParserBuilder implements JwtParserBuilder { @SuppressWarnings("deprecation") //TODO: remove for 1.0 private SigningKeyResolver signingKeyResolver = null; - private Registry encAlgs = Jwts.ENC.get(); + private Registry encAlgs = Jwe.alg.registry(); - private Registry> keyAlgs = Jwts.KEY.get(); + private Registry> keyAlgs = Jwe.enc.registry(); - private Registry> sigAlgs = Jwts.SIG.get(); + private Registry> sigAlgs = Jws.alg.registry(); private Registry zipAlgs = Jwts.ZIP.get(); diff --git a/impl/src/main/java/io/jsonwebtoken/impl/DefaultProtectedHeader.java b/impl/src/main/java/io/jsonwebtoken/impl/DefaultProtectedHeader.java index e93dedbf2..216bfd15d 100644 --- a/impl/src/main/java/io/jsonwebtoken/impl/DefaultProtectedHeader.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/DefaultProtectedHeader.java @@ -15,7 +15,7 @@ */ package io.jsonwebtoken.impl; -import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.Jws; import io.jsonwebtoken.ProtectedHeader; import io.jsonwebtoken.impl.lang.Parameter; import io.jsonwebtoken.impl.lang.Parameters; @@ -62,8 +62,8 @@ public class DefaultProtectedHeader extends DefaultHeader implements ProtectedHe static boolean isCandidate(ParameterMap map) { String id = map.get(DefaultHeader.ALGORITHM); - return Strings.hasText(id) && !id.equalsIgnoreCase(Jwts.SIG.NONE.getId()); // alg cannot be empty or 'none' -// return (Strings.hasText(id) && !Jwts.SIG.NONE.equals(Jwts.SIG.get().get(id))) || + return Strings.hasText(id) && !id.equalsIgnoreCase(Jws.alg.NONE.getId()); // alg cannot be empty or 'none' +// return (Strings.hasText(id) && !Jws.alg.NONE.equals(Jws.alg.registry().get(id))) || // map.get(JKU) != null || // map.get(JWK) != null || // !Collections.isEmpty(map.get(CRIT)) || diff --git a/impl/src/main/java/io/jsonwebtoken/impl/security/DefaultMacAlgorithm.java b/impl/src/main/java/io/jsonwebtoken/impl/security/DefaultMacAlgorithm.java index e92277aed..021b9b546 100644 --- a/impl/src/main/java/io/jsonwebtoken/impl/security/DefaultMacAlgorithm.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/security/DefaultMacAlgorithm.java @@ -187,7 +187,7 @@ protected void validateKey(Key k, boolean signing) { msg += " The JWT " + "JWA Specification (RFC 7518, Section 3.2) states that keys used with " + id + " MUST have a " + "size >= " + minKeyBitLength + " bits (the key size must be greater than or equal to the hash " + - "output size). Consider using the Jwts.SIG." + id + ".key() " + + "output size). Consider using the Jws.alg." + id + ".key() " + "builder to create a key guaranteed to be secure enough for " + id + ". See " + "https://tools.ietf.org/html/rfc7518#section-3.2 for more information."; } else { //custom algorithm - just indicate required key length: diff --git a/impl/src/main/java/io/jsonwebtoken/impl/security/RsaSignatureAlgorithm.java b/impl/src/main/java/io/jsonwebtoken/impl/security/RsaSignatureAlgorithm.java index f10747b4f..ea6411fba 100644 --- a/impl/src/main/java/io/jsonwebtoken/impl/security/RsaSignatureAlgorithm.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/security/RsaSignatureAlgorithm.java @@ -191,7 +191,7 @@ protected void validateKey(Key key, boolean signing) { String msg = "The RSA " + keyType(signing) + " key size (aka modulus bit length) is " + size + " bits " + "which is not secure enough for the " + id + " algorithm. The JWT JWA Specification " + "(RFC 7518, Section " + section + ") states that RSA keys MUST have a size >= " + - MIN_KEY_BIT_LENGTH + " bits. Consider using the Jwts.SIG." + id + + MIN_KEY_BIT_LENGTH + " bits. Consider using the Jws.alg." + id + ".keyPair() builder to create a KeyPair guaranteed to be secure enough for " + id + ". See " + "https://tools.ietf.org/html/rfc7518#section-" + section + " for more information."; throw new WeakKeyException(msg); diff --git a/impl/src/main/java/io/jsonwebtoken/impl/security/SecretJwkFactory.java b/impl/src/main/java/io/jsonwebtoken/impl/security/SecretJwkFactory.java index 36238cc4e..ebfb18fee 100644 --- a/impl/src/main/java/io/jsonwebtoken/impl/security/SecretJwkFactory.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/security/SecretJwkFactory.java @@ -16,7 +16,8 @@ package io.jsonwebtoken.impl.security; import io.jsonwebtoken.Identifiable; -import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.Jwe; +import io.jsonwebtoken.Jws; import io.jsonwebtoken.impl.lang.Bytes; import io.jsonwebtoken.impl.lang.ParameterReadable; import io.jsonwebtoken.impl.lang.RequiredParameterReader; @@ -114,7 +115,7 @@ protected SecretJwk createJwkFromValues(JwkContext ctx) { // KeyAlgorithm and AeadAlgorithm use cases, so that's our default. int kBitLen = (int) Bytes.bitLength(bytes); - if (ctx.isSigUse() || kBitLen > Jwts.SIG.HS256.getKeyBitLength()) { + if (ctx.isSigUse() || kBitLen > Jws.alg.HS256.getKeyBitLength()) { // The only JWA SecretKey signature algorithms are HS256, HS384, HS512, so choose based on bit length: key = Keys.hmacShaKeyFor(bytes); } else { @@ -125,9 +126,9 @@ protected SecretJwk createJwkFromValues(JwkContext ctx) { } //otherwise 'alg' was specified, ensure it's valid for secret key use: - Identifiable alg = Jwts.SIG.get().get(algId); - if (alg == null) alg = Jwts.KEY.get().get(algId); - if (alg == null) alg = Jwts.ENC.get().get(algId); + Identifiable alg = Jws.alg.registry().get(algId); + if (alg == null) alg = Jwe.enc.registry().get(algId); + if (alg == null) alg = Jwe.alg.registry().get(algId); if (alg != null) assertSymmetric(alg); // if we found a standard alg, it must be a symmetric key algorithm if (alg instanceof MacAlgorithm) { diff --git a/impl/src/main/java/io/jsonwebtoken/impl/security/StandardEncryptionAlgorithms.java b/impl/src/main/java/io/jsonwebtoken/impl/security/StandardEncryptionAlgorithms.java index 5ee236167..74af22502 100644 --- a/impl/src/main/java/io/jsonwebtoken/impl/security/StandardEncryptionAlgorithms.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/security/StandardEncryptionAlgorithms.java @@ -19,7 +19,7 @@ import io.jsonwebtoken.lang.Collections; import io.jsonwebtoken.security.AeadAlgorithm; -@SuppressWarnings("unused") // used via reflection in io.jsonwebtoken.Jwts.ENC +@SuppressWarnings("unused") // used via reflection in io.jsonwebtoken.Jwe.alg public final class StandardEncryptionAlgorithms extends IdRegistry { public static final String NAME = "JWE Encryption Algorithm"; diff --git a/impl/src/main/java/io/jsonwebtoken/impl/security/StandardKeyAlgorithms.java b/impl/src/main/java/io/jsonwebtoken/impl/security/StandardKeyAlgorithms.java index 6a03dcdbb..2eef7b88d 100644 --- a/impl/src/main/java/io/jsonwebtoken/impl/security/StandardKeyAlgorithms.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/security/StandardKeyAlgorithms.java @@ -132,7 +132,7 @@ public static int estimateIterations(KeyAlgorithm alg, long final int PASSWORD_LENGTH = 8; final JweHeader HEADER = new DefaultJweHeader(); - final AeadAlgorithm ENC_ALG = Jwts.ENC.A128GCM; // not used, needed to satisfy API + final AeadAlgorithm ENC_ALG = Jwe.alg.A128GCM; // not used, needed to satisfy API if (alg instanceof Pbes2HsAkwAlgorithm) { // Strip away all things that cause time during computation except for the actual hashing algorithm: diff --git a/impl/src/main/java/io/jsonwebtoken/impl/security/StandardSecureDigestAlgorithms.java b/impl/src/main/java/io/jsonwebtoken/impl/security/StandardSecureDigestAlgorithms.java index b61875d6c..71d5c47b6 100644 --- a/impl/src/main/java/io/jsonwebtoken/impl/security/StandardSecureDigestAlgorithms.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/security/StandardSecureDigestAlgorithms.java @@ -24,7 +24,7 @@ import java.security.Key; import java.security.PrivateKey; -@SuppressWarnings("unused") // used via reflection in io.jsonwebtoken.Jwts.SIG +@SuppressWarnings("unused") // used via reflection in io.jsonwebtoken.Jws.alg public final class StandardSecureDigestAlgorithms extends IdRegistry> { public static final String NAME = "JWS Digital Signature or MAC"; diff --git a/impl/src/test/groovy/io/jsonwebtoken/JwtParserTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/JwtParserTest.groovy index d6c1cf9ec..8dd4440c0 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/JwtParserTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/JwtParserTest.groovy @@ -1661,7 +1661,7 @@ class JwtParserTest { def key = TestKeys.A256GCM def jwe = Jwts.builder().claim("hello", "world") .compressWith(Jwts.ZIP.DEF) - .encryptWith(key, Jwts.ENC.A256GCM) + .encryptWith(key, Jwe.alg.A256GCM) .compact() //now build a parser with no decompression algs (which should disable decompression) @@ -1688,7 +1688,7 @@ class JwtParserTest { // create a compressed JWE first: def key = TestKeys.HS256 def jws = Jwts.builder().claim("hello", "world") - .signWith(key, Jwts.SIG.HS256) + .signWith(key, Jws.alg.HS256) .compact() //now build a parser with no signature algs, which should completely disable signature verification @@ -1717,7 +1717,7 @@ class JwtParserTest { // create a compressed JWE first: def key = TestKeys.A256GCM def jwe = Jwts.builder().claim("hello", "world") - .encryptWith(key, Jwts.ENC.A256GCM) + .encryptWith(key, Jwe.alg.A256GCM) .compact() //now build a parser with no encryption algs, which should completely disable decryption @@ -1744,7 +1744,7 @@ class JwtParserTest { // create a compressed JWE first: def key = TestKeys.A256GCM def jwe = Jwts.builder().claim("hello", "world") - .encryptWith(key, Jwts.ENC.A256GCM) + .encryptWith(key, Jwe.alg.A256GCM) .compact() //now build a parser with no key management algs, which should completely disable decryption diff --git a/impl/src/test/groovy/io/jsonwebtoken/JwtsTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/JwtsTest.groovy index c232a1ade..a6bb5bad3 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/JwtsTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/JwtsTest.groovy @@ -142,7 +142,7 @@ class JwtsTest { def data = Strings.utf8(("$h.$c" as String)) def payload = Streams.of(data) def request = new DefaultSecureRequest<>(payload, null, null, key) - def result = Jwts.SIG.HS256.digest(request) + def result = Jws.alg.HS256.digest(request) def sig = Encoders.BASE64URL.encode(result) def compact = "$h.$c.$sig" as String try { @@ -338,7 +338,7 @@ class JwtsTest { @Test void testParseWithMissingRequiredSignature() { - Key key = Jwts.SIG.HS256.key().build() + Key key = Jws.alg.HS256.key().build() String compact = Jwts.builder().setSubject('foo').signWith(key).compact() int i = compact.lastIndexOf('.') String missingSig = compact.substring(0, i + 1) @@ -475,7 +475,7 @@ class JwtsTest { @Test void testUncompressedJwt() { - def alg = Jwts.SIG.HS256 + def alg = Jws.alg.HS256 SecretKey key = alg.key().build() String id = UUID.randomUUID().toString() @@ -497,7 +497,7 @@ class JwtsTest { @Test void testCompressedJwtWithDeflate() { - def alg = Jwts.SIG.HS256 + def alg = Jws.alg.HS256 SecretKey key = alg.key().build() String id = UUID.randomUUID().toString() @@ -519,7 +519,7 @@ class JwtsTest { @Test void testCompressedJwtWithGZIP() { - def alg = Jwts.SIG.HS256 + def alg = Jws.alg.HS256 SecretKey key = alg.key().build() String id = UUID.randomUUID().toString() @@ -541,7 +541,7 @@ class JwtsTest { @Test void testCompressedWithCustomResolver() { - def alg = Jwts.SIG.HS256 + def alg = Jws.alg.HS256 SecretKey key = alg.key().build() String id = UUID.randomUUID().toString() @@ -580,7 +580,7 @@ class JwtsTest { @Test(expected = UnsupportedJwtException.class) void testCompressedJwtWithUnrecognizedHeader() { - def alg = Jwts.SIG.HS256 + def alg = Jws.alg.HS256 SecretKey key = alg.key().build() String id = UUID.randomUUID().toString() @@ -599,7 +599,7 @@ class JwtsTest { @Test void testCompressStringPayloadWithDeflate() { - def alg = Jwts.SIG.HS256 + def alg = Jws.alg.HS256 SecretKey key = alg.key().build() String payload = "this is my test for a payload" @@ -616,82 +616,82 @@ class JwtsTest { @Test void testHS256() { - testHmac(Jwts.SIG.HS256) + testHmac(Jws.alg.HS256) } @Test void testHS384() { - testHmac(Jwts.SIG.HS384) + testHmac(Jws.alg.HS384) } @Test void testHS512() { - testHmac(Jwts.SIG.HS512) + testHmac(Jws.alg.HS512) } @Test void testRS256() { - testRsa(Jwts.SIG.RS256) + testRsa(Jws.alg.RS256) } @Test void testRS384() { - testRsa(Jwts.SIG.RS384) + testRsa(Jws.alg.RS384) } @Test void testRS512() { - testRsa(Jwts.SIG.RS512) + testRsa(Jws.alg.RS512) } @Test void testPS256() { - testRsa(Jwts.SIG.PS256) + testRsa(Jws.alg.PS256) } @Test void testPS384() { - testRsa(Jwts.SIG.PS384) + testRsa(Jws.alg.PS384) } @Test void testPS512() { - testRsa(Jwts.SIG.PS512) + testRsa(Jws.alg.PS512) } @Test void testES256() { - testEC(Jwts.SIG.ES256) + testEC(Jws.alg.ES256) } @Test void testES384() { - testEC(Jwts.SIG.ES384) + testEC(Jws.alg.ES384) } @Test void testES512() { - testEC(Jwts.SIG.ES512) + testEC(Jws.alg.ES512) } @Test void testEdDSA() { - testEC(Jwts.SIG.EdDSA) + testEC(Jws.alg.EdDSA) } @Test void testEd25519() { - testEC(Jwts.SIG.EdDSA, TestKeys.forAlgorithm(Jwks.CRV.Ed25519).pair) + testEC(Jws.alg.EdDSA, TestKeys.forAlgorithm(Jwks.CRV.Ed25519).pair) } @Test void testEd448() { - testEC(Jwts.SIG.EdDSA, TestKeys.forAlgorithm(Jwks.CRV.Ed448).pair) + testEC(Jws.alg.EdDSA, TestKeys.forAlgorithm(Jwks.CRV.Ed448).pair) } @Test void testES256WithPrivateKeyValidation() { - def alg = Jwts.SIG.ES256 + def alg = Jws.alg.ES256 try { testEC(alg, true) fail("EC private keys cannot be used to validate EC signatures.") @@ -703,9 +703,9 @@ class JwtsTest { @Test(expected = WeakKeyException) void testparseSignedClaimsWithWeakHmacKey() { - def alg = Jwts.SIG.HS384 + def alg = Jws.alg.HS384 def key = alg.key().build() - def weakKey = Jwts.SIG.HS256.key().build() + def weakKey = Jws.alg.HS256.key().build() String jws = Jwts.builder().setSubject("Foo").signWith(key, alg).compact() @@ -775,7 +775,7 @@ class JwtsTest { def withoutSignature = "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZXN0IjoidGVzdCIsImlhdCI6MTQ2NzA2NTgyN30" def invalidEncodedSignature = "_____wAAAAD__________7zm-q2nF56E87nKwvxjJVH_____AAAAAP__________vOb6racXnoTzucrC_GMlUQ" String jws = withoutSignature + '.' + invalidEncodedSignature - def keypair = Jwts.SIG.ES256.keyPair().build() + def keypair = Jws.alg.ES256.keyPair().build() Jwts.parser().setSigningKey(keypair.public).build().parseSignedClaims(jws) } @@ -784,7 +784,7 @@ class JwtsTest { void testparseSignedClaimsWithUnsignedJwt() { //create random signing key for testing: - def alg = Jwts.SIG.HS256 + def alg = Jws.alg.HS256 SecretKey key = alg.key().build() String notSigned = Jwts.builder().setSubject("Foo").compact() @@ -1052,7 +1052,7 @@ class JwtsTest { */ @Test void testParseJwsWithCustomSignatureAlgorithm() { - def realAlg = Jwts.SIG.HS256 // any alg will do, we're going to wrap it + def realAlg = Jws.alg.HS256 // any alg will do, we're going to wrap it def key = TestKeys.HS256 def id = realAlg.getId() + 'X' // custom id def alg = new TestMacAlgorithm(id: id, delegate: realAlg) @@ -1071,7 +1071,7 @@ class JwtsTest { */ @Test void testParseJweWithCustomEncryptionAlgorithm() { - def realAlg = Jwts.ENC.A128GCM // any alg will do, we're going to wrap it + def realAlg = Jwe.alg.A128GCM // any alg will do, we're going to wrap it def key = realAlg.key().build() def enc = realAlg.getId() + 'X' // custom id def encAlg = new AeadAlgorithm() { @@ -1201,7 +1201,7 @@ class JwtsTest { void testForgedTokenWithSwappedHeaderUsingNoneAlgorithm() { //create random signing key for testing: - def alg = Jwts.SIG.HS256 + def alg = Jws.alg.HS256 SecretKey key = alg.key().build() //this is a 'real', valid JWT: @@ -1340,13 +1340,13 @@ class JwtsTest { @Test void testSecretKeyJwes() { - def algs = Jwts.KEY.get().values().findAll({ it -> + def algs = Jwe.enc.registry().values().findAll({ it -> it instanceof DirectKeyAlgorithm || it instanceof SecretKeyAlgorithm })// as Collection> for (KeyAlgorithm alg : algs) { - for (AeadAlgorithm enc : Jwts.ENC.get().values()) { + for (AeadAlgorithm enc : Jwe.alg.registry().values()) { SecretKey key = alg instanceof SecretKeyAlgorithm ? ((SecretKeyAlgorithm) alg).key().build() : @@ -1375,7 +1375,7 @@ class JwtsTest { for (CompressionCodec codec : codecs) { - for (AeadAlgorithm enc : Jwts.ENC.get().values()) { + for (AeadAlgorithm enc : Jwe.alg.registry().values()) { SecretKey key = enc.key().build() @@ -1402,7 +1402,7 @@ class JwtsTest { for (CompressionAlgorithm zip : codecs) { - for (AeadAlgorithm enc : Jwts.ENC.get().values()) { + for (AeadAlgorithm enc : Jwe.alg.registry().values()) { SecretKey key = enc.key().build() @@ -1431,7 +1431,7 @@ class JwtsTest { for (CompressionAlgorithm zip : codecs) { - for (AeadAlgorithm enc : Jwts.ENC.get().values()) { + for (AeadAlgorithm enc : Jwe.alg.registry().values()) { SecretKey key = enc.key().build() @@ -1461,7 +1461,7 @@ class JwtsTest { for (CompressionAlgorithm zip : codecs) { - for (AeadAlgorithm enc : Jwts.ENC.get().values()) { + for (AeadAlgorithm enc : Jwe.alg.registry().values()) { SecretKey key = enc.key().build() @@ -1490,7 +1490,7 @@ class JwtsTest { @Test void testPasswordJwes() { - def algs = Jwts.KEY.get().values().findAll({ it -> + def algs = Jwe.enc.registry().values().findAll({ it -> it instanceof Pbes2HsAkwAlgorithm })// as Collection> @@ -1498,7 +1498,7 @@ class JwtsTest { for (KeyAlgorithm alg : algs) { - for (AeadAlgorithm enc : Jwts.ENC.get().values()) { + for (AeadAlgorithm enc : Jwe.alg.registry().values()) { // encrypt: String jwe = Jwts.builder() @@ -1524,7 +1524,7 @@ class JwtsTest { // encrypt: String jwe = Jwts.builder() .claim('foo', 'bar') - .encryptWith(key, Jwts.ENC.A256GCM) // should auto choose KeyAlg PBES2_HS512_A256KW + .encryptWith(key, Jwe.alg.A256GCM) // should auto choose KeyAlg PBES2_HS512_A256KW .compact() //decrypt: @@ -1533,7 +1533,7 @@ class JwtsTest { .build() .parseEncryptedClaims(jwe) assertEquals 'bar', jwt.getPayload().get('foo') - assertEquals Jwts.KEY.PBES2_HS512_A256KW, Jwts.KEY.get().forKey(jwt.getHeader().getAlgorithm()) + assertEquals Jwe.enc.PBES2_HS512_A256KW, Jwe.enc.registry().forKey(jwt.getHeader().getAlgorithm()) } @Test @@ -1541,7 +1541,7 @@ class JwtsTest { def pairs = [TestKeys.RS256.pair, TestKeys.RS384.pair, TestKeys.RS512.pair] - def algs = Jwts.KEY.get().values().findAll({ it -> + def algs = Jwe.enc.registry().values().findAll({ it -> it instanceof DefaultRsaKeyAlgorithm })// as Collection> @@ -1552,7 +1552,7 @@ class JwtsTest { for (KeyAlgorithm alg : algs) { - for (AeadAlgorithm enc : Jwts.ENC.get().values()) { + for (AeadAlgorithm enc : Jwe.alg.registry().values()) { // encrypt: String jwe = Jwts.builder() @@ -1576,7 +1576,7 @@ class JwtsTest { def pairs = [TestKeys.ES256.pair, TestKeys.ES384.pair, TestKeys.ES512.pair] - def algs = Jwts.KEY.get().values().findAll({ it -> + def algs = Jwe.enc.registry().values().findAll({ it -> it.getId().startsWith("ECDH-ES") }) @@ -1587,7 +1587,7 @@ class JwtsTest { for (KeyAlgorithm alg : algs) { - for (AeadAlgorithm enc : Jwts.ENC.get().values()) { + for (AeadAlgorithm enc : Jwe.alg.registry().values()) { // encrypt: String jwe = Jwts.builder() @@ -1611,7 +1611,7 @@ class JwtsTest { def pairs = [TestKeys.X25519.pair, TestKeys.X448.pair] - def algs = Jwts.KEY.get().values().findAll({ it -> + def algs = Jwe.enc.registry().values().findAll({ it -> it.getId().startsWith("ECDH-ES") }) @@ -1621,7 +1621,7 @@ class JwtsTest { def privKey = pair.getPrivate() for (KeyAlgorithm alg : algs) { - for (AeadAlgorithm enc : Jwts.ENC.get().values()) { + for (AeadAlgorithm enc : Jwe.alg.registry().values()) { String jwe = encrypt(pubKey, alg, enc) def jwt = decrypt(jwe, privKey) assertEquals 'bar', jwt.getPayload().get('foo') @@ -1638,14 +1638,14 @@ class JwtsTest { void testEdwardsCurveEncryptionWithSigningKeys() { def pairs = [TestKeys.Ed25519.pair, TestKeys.Ed448.pair] // signing keys, can't be used - def algs = Jwts.KEY.get().values().findAll({ it -> + def algs = Jwe.enc.registry().values().findAll({ it -> it.getId().startsWith("ECDH-ES") }) for (KeyPair pair : pairs) { def pubKey = pair.getPublic() for (KeyAlgorithm alg : algs) { - for (AeadAlgorithm enc : Jwts.ENC.get().values()) { + for (AeadAlgorithm enc : Jwe.alg.registry().values()) { try { encrypt(pubKey, alg, enc) fail() @@ -1672,13 +1672,13 @@ class JwtsTest { new KeyPair(TestKeys.X448.pair.public, TestKeys.Ed448.pair.private) ] - def algs = Jwts.KEY.get().values().findAll({ it -> + def algs = Jwe.enc.registry().values().findAll({ it -> it.getId().startsWith("ECDH-ES") }) for (KeyPair pair : pairs) { for (KeyAlgorithm alg : algs) { - for (AeadAlgorithm enc : Jwts.ENC.get().values()) { + for (AeadAlgorithm enc : Jwe.alg.registry().values()) { String jwe = encrypt(pair.getPublic(), alg, enc) PrivateKey key = pair.getPrivate() try { diff --git a/impl/src/test/groovy/io/jsonwebtoken/RFC7797Test.groovy b/impl/src/test/groovy/io/jsonwebtoken/RFC7797Test.groovy index b32036f89..a33fda9da 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/RFC7797Test.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/RFC7797Test.groovy @@ -37,7 +37,7 @@ class RFC7797Test { @Test void testJwe() { try { - Jwts.builder().content('hello').encryptWith(TestKeys.A128GCM, Jwts.ENC.A128GCM) + Jwts.builder().content('hello').encryptWith(TestKeys.A128GCM, Jwe.alg.A128GCM) .encodePayload(false) // not allowed with JWE .compact() fail() diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJweTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJweTest.groovy index b21e45249..355f75e54 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJweTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJweTest.groovy @@ -15,6 +15,7 @@ */ package io.jsonwebtoken.impl +import io.jsonwebtoken.Jwe import io.jsonwebtoken.Jwts import io.jsonwebtoken.io.Encoders import io.jsonwebtoken.security.AeadAlgorithm @@ -27,7 +28,7 @@ class DefaultJweTest { @Test void testToString() { - def alg = Jwts.ENC.A128CBC_HS256 as AeadAlgorithm + def alg = Jwe.alg.A128CBC_HS256 as AeadAlgorithm def key = alg.key().build() String compact = Jwts.builder().claim('foo', 'bar').encryptWith(key, alg).compact() def jwe = Jwts.parser().decryptWith(key).build().parseEncryptedClaims(compact) @@ -39,7 +40,7 @@ class DefaultJweTest { @Test void testEqualsAndHashCode() { - def alg = Jwts.ENC.A128CBC_HS256 as AeadAlgorithm + def alg = Jwe.alg.A128CBC_HS256 as AeadAlgorithm def key = alg.key().build() String compact = Jwts.builder().claim('foo', 'bar').encryptWith(key, alg).compact() def parser = Jwts.parser().decryptWith(key).build() diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwsTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwsTest.groovy index 1511eb103..25baf6e82 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwsTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwsTest.groovy @@ -15,6 +15,7 @@ */ package io.jsonwebtoken.impl +import io.jsonwebtoken.Jws import io.jsonwebtoken.JwsHeader import io.jsonwebtoken.Jwts import io.jsonwebtoken.impl.lang.Bytes @@ -42,7 +43,7 @@ class DefaultJwsTest { @Test void testToString() { //create random signing key for testing: - def alg = Jwts.SIG.HS256 + def alg = Jws.alg.HS256 def key = alg.key().build() String compact = Jwts.builder().claim('foo', 'bar').signWith(key, alg).compact() int i = compact.lastIndexOf('.') @@ -53,7 +54,7 @@ class DefaultJwsTest { @Test void testEqualsAndHashCode() { - def alg = Jwts.SIG.HS256 + def alg = Jws.alg.HS256 def key = alg.key().build() String compact = Jwts.builder().claim('foo', 'bar').signWith(key, alg).compact() def parser = Jwts.parser().verifyWith(key).build() diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtBuilderTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtBuilderTest.groovy index 93963e005..a79b57619 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtBuilderTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtBuilderTest.groovy @@ -16,9 +16,7 @@ package io.jsonwebtoken.impl import com.fasterxml.jackson.databind.ObjectMapper -import io.jsonwebtoken.Claims -import io.jsonwebtoken.Jwts -import io.jsonwebtoken.SignatureAlgorithm +import io.jsonwebtoken.* import io.jsonwebtoken.impl.io.Streams import io.jsonwebtoken.impl.io.TestSerializer import io.jsonwebtoken.impl.lang.Services @@ -98,7 +96,7 @@ class DefaultJwtBuilderTest { replay provider def b = new DefaultJwtBuilder().provider(provider) - .setSubject('me').signWith(Jwts.SIG.HS256.key().build(), alg) + .setSubject('me').signWith(Jws.alg.HS256.key().build(), alg) assertSame provider, b.provider b.compact() verify provider @@ -140,7 +138,7 @@ class DefaultJwtBuilderTest { } def b = new DefaultJwtBuilder().random(random) - .setSubject('me').signWith(Jwts.SIG.HS256.key().build(), alg) + .setSubject('me').signWith(Jws.alg.HS256.key().build(), alg) assertSame random, b.secureRandom b.compact() assertTrue called[0] @@ -315,8 +313,8 @@ class DefaultJwtBuilderTest { builder.subject("Joe") // make Claims JWS - for (SecureDigestAlgorithm alg : Jwts.SIG.get().values()) { - if (alg.equals(Jwts.SIG.NONE)) { // skip + for (SecureDigestAlgorithm alg : Jws.alg.registry().values()) { + if (alg.equals(Jws.alg.NONE)) { // skip continue; } def key, vkey @@ -522,7 +520,7 @@ class DefaultJwtBuilderTest { void testSignWithNoneAlgorithm() { def key = TestKeys.HS256 try { - builder.signWith(key, Jwts.SIG.NONE) + builder.signWith(key, Jws.alg.NONE) fail() } catch (IllegalArgumentException expected) { String msg = "The 'none' JWS algorithm cannot be used to sign JWTs." @@ -533,7 +531,7 @@ class DefaultJwtBuilderTest { @Test void testSignWithPublicKey() { def key = TestKeys.RS256.pair.public - def alg = Jwts.SIG.RS256 + def alg = Jws.alg.RS256 try { builder.signWith(key, alg) fail() @@ -544,7 +542,7 @@ class DefaultJwtBuilderTest { @Test void testCompactSimplestPayload() { - def enc = Jwts.ENC.A128GCM + def enc = Jwe.alg.A128GCM def key = enc.key().build() def jwe = builder.setPayload("me").encryptWith(key, enc).compact() def jwt = Jwts.parser().decryptWith(key).build().parseEncryptedContent(jwe) @@ -553,7 +551,7 @@ class DefaultJwtBuilderTest { @Test void testCompactSimplestClaims() { - def enc = Jwts.ENC.A128GCM + def enc = Jwe.alg.A128GCM def key = enc.key().build() def jwe = builder.setSubject('joe').encryptWith(key, enc).compact() def jwt = Jwts.parser().decryptWith(key).build().parseEncryptedClaims(jwe) @@ -564,7 +562,7 @@ class DefaultJwtBuilderTest { void testSignWithAndEncryptWith() { def key = TestKeys.HS256 try { - builder.signWith(key).encryptWith(key, Jwts.ENC.A128GCM).compact() + builder.signWith(key).encryptWith(key, Jwe.alg.A128GCM).compact() fail() } catch (IllegalStateException expected) { String msg = "Both 'signWith' and 'encryptWith' cannot be specified. Choose either one." @@ -576,7 +574,7 @@ class DefaultJwtBuilderTest { void testEmptyPayloadAndClaimsJwe() { def key = TestKeys.HS256 try { - builder.encryptWith(key, Jwts.ENC.A128GCM).compact() + builder.encryptWith(key, Jwe.alg.A128GCM).compact() fail() } catch (IllegalStateException expected) { String msg = "Encrypted JWTs must have either 'claims' or non-empty 'content'." diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtHeaderBuilderTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtHeaderBuilderTest.groovy index 049f56447..4e99a9cd9 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtHeaderBuilderTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtHeaderBuilderTest.groovy @@ -15,10 +15,7 @@ */ package io.jsonwebtoken.impl -import io.jsonwebtoken.JweHeader -import io.jsonwebtoken.JwsHeader -import io.jsonwebtoken.Jwts -import io.jsonwebtoken.ProtectedHeader +import io.jsonwebtoken.* import io.jsonwebtoken.impl.io.Streams import io.jsonwebtoken.impl.lang.Bytes import io.jsonwebtoken.impl.security.DefaultHashAlgorithm @@ -414,8 +411,8 @@ class DefaultJwtHeaderBuilderTest { @Test void testEncryptionAlgorithm() { - def enc = Jwts.ENC.A256GCM.getId() - header = builder.add('alg', Jwts.KEY.A192KW.getId()).add('enc', enc).build() as JweHeader + def enc = Jwe.alg.A256GCM.getId() + header = builder.add('alg', Jwe.enc.A192KW.getId()).add('enc', enc).build() as JweHeader assertEquals enc, header.getEncryptionAlgorithm() } @@ -495,7 +492,7 @@ class DefaultJwtHeaderBuilderTest { assertEquals new DefaultJwsHeader([foo: 'bar', alg: 'HS256']), builder.build() // add JWE required property: - builder.put(DefaultJweHeader.ENCRYPTION_ALGORITHM.getId(), Jwts.ENC.A256GCM.getId()) + builder.put(DefaultJweHeader.ENCRYPTION_ALGORITHM.getId(), Jwe.alg.A256GCM.getId()) assertEquals new DefaultJweHeader([foo: 'bar', alg: 'HS256', enc: 'A256GCM']), builder.build() } diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtParserBuilderTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtParserBuilderTest.groovy index ef2ab49a3..111ec99ef 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtParserBuilderTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtParserBuilderTest.groovy @@ -144,7 +144,7 @@ class DefaultJwtParserBuilderTest { def p = builder.deserializeJsonWith(deserializer) assertSame deserializer, p.@deserializer - def alg = Jwts.SIG.HS256 + def alg = Jws.alg.HS256 def key = alg.key().build() String jws = Jwts.builder().claim('foo', 'bar').signWith(key, alg).compact() @@ -232,10 +232,10 @@ class DefaultJwtParserBuilderTest { @Test void testAddEncryptionAlgorithmsOverrideDefaults() { - final String standardId = Jwts.ENC.A256GCM.getId() + final String standardId = Jwe.alg.A256GCM.getId() def header = Jwts.header().add('enc', standardId).build() def parser = builder.build() - assertSame Jwts.ENC.A256GCM, parser.encAlgs.apply(header) // standard implementation default + assertSame Jwe.alg.A256GCM, parser.encAlgs.apply(header) // standard implementation default def custom = new TestAeadAlgorithm(id: standardId) // custom impl with standard identifier parser = builder.enc().add(custom).and().build() @@ -259,7 +259,7 @@ class DefaultJwtParserBuilderTest { @Test void testCaseSensitiveEncryptionAlgorithm() { - def alg = Jwts.ENC.A256GCM + def alg = Jwe.alg.A256GCM def standard = Jwts.header().add('alg', 'foo').add('enc', alg.id).build() def nonStandard = Jwts.header().add('alg', 'foo').add('enc', alg.id.toLowerCase()).build() def parser = builder.build() @@ -275,10 +275,10 @@ class DefaultJwtParserBuilderTest { @Test void testAddKeyAlgorithmsOverrideDefaults() { - final String standardId = Jwts.KEY.A256GCMKW.id - def header = Jwts.header().add('enc', Jwts.ENC.A256GCM.id).add('alg', standardId).build() + final String standardId = Jwe.enc.A256GCMKW.id + def header = Jwts.header().add('enc', Jwe.alg.A256GCM.id).add('alg', standardId).build() def parser = builder.build() - assertSame Jwts.KEY.A256GCMKW, parser.keyAlgs.apply(header) // standard implementation default + assertSame Jwe.enc.A256GCMKW, parser.keyAlgs.apply(header) // standard implementation default def custom = new TestKeyAlgorithm(id: standardId) // custom impl with standard identifier parser = builder.key().add(custom).and().build() @@ -304,8 +304,8 @@ class DefaultJwtParserBuilderTest { @Test void testCaseSensitiveKeyAlgorithm() { - def alg = Jwts.KEY.A256GCMKW - def hb = Jwts.header().add('enc', Jwts.ENC.A256GCM.id) + def alg = Jwe.enc.A256GCMKW + def hb = Jwts.header().add('enc', Jwe.alg.A256GCM.id) def standard = hb.add('alg', alg.id).build() def nonStandard = hb.add('alg', alg.id.toLowerCase()).build() def parser = builder.build() @@ -321,10 +321,10 @@ class DefaultJwtParserBuilderTest { @Test void testAddSignatureAlgorithmsOverrideDefaults() { - final String standardId = Jwts.SIG.HS256.id + final String standardId = Jws.alg.HS256.id def header = Jwts.header().add('alg', standardId).build() def parser = builder.build() - assertSame Jwts.SIG.HS256, parser.sigAlgs.apply(header) // standard implementation default + assertSame Jws.alg.HS256, parser.sigAlgs.apply(header) // standard implementation default def custom = new TestMacAlgorithm(id: standardId) // custom impl with standard identifier parser = builder.sig().add(custom).and().build() @@ -348,7 +348,7 @@ class DefaultJwtParserBuilderTest { @Test void testCaseSensitiveSignatureAlgorithm() { - def alg = Jwts.SIG.HS256 + def alg = Jws.alg.HS256 def hb = Jwts.header().add('alg', alg.id) def standard = hb.build() def nonStandard = hb.add('alg', alg.id.toLowerCase()).build() diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtParserTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtParserTest.groovy index 4c41142c2..ecdd00cf4 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtParserTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtParserTest.groovy @@ -83,8 +83,8 @@ class DefaultJwtParserTest { def pb = Jwts.parser().deserializeJsonWith(deserializer) assertFalse invoked - def key = Jwts.SIG.HS256.key().build() - String jws = Jwts.builder().claim('foo', 'bar').signWith(key, Jwts.SIG.HS256).compact() + def key = Jws.alg.HS256.key().build() + String jws = Jwts.builder().claim('foo', 'bar').signWith(key, Jws.alg.HS256).compact() assertFalse invoked assertEquals 'bar', pb.verifyWith(key).build().parseSignedClaims(jws).getPayload().get('foo') diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultMutableJweHeaderTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultMutableJweHeaderTest.groovy index 76b647341..e8ed0124e 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultMutableJweHeaderTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultMutableJweHeaderTest.groovy @@ -15,6 +15,7 @@ */ package io.jsonwebtoken.impl +import io.jsonwebtoken.Jwe import io.jsonwebtoken.Jwts import io.jsonwebtoken.impl.io.Streams import io.jsonwebtoken.impl.lang.Bytes @@ -300,7 +301,7 @@ class DefaultMutableJweHeaderTest { @Test void testEncryptionAlgorithm() { - def enc = Jwts.ENC.A256GCM.getId() + def enc = Jwe.alg.A256GCM.getId() header.put('enc', enc) assertEquals enc, header.getEncryptionAlgorithm() } diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/security/AbstractSecureDigestAlgorithmTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/security/AbstractSecureDigestAlgorithmTest.groovy index 166762c4d..305fcf65b 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/security/AbstractSecureDigestAlgorithmTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/security/AbstractSecureDigestAlgorithmTest.groovy @@ -15,7 +15,7 @@ */ package io.jsonwebtoken.impl.security -import io.jsonwebtoken.Jwts +import io.jsonwebtoken.Jws import io.jsonwebtoken.impl.io.Streams import io.jsonwebtoken.lang.Strings import io.jsonwebtoken.security.SecureRequest @@ -36,17 +36,17 @@ class AbstractSecureDigestAlgorithmTest { @Test void testSignAndVerifyWithExplicitProvider() { Provider provider = Security.getProvider('BC') - def pair = Jwts.SIG.RS256.keyPair().build() + def pair = Jws.alg.RS256.keyPair().build() byte[] data = Strings.utf8('foo') def payload = Streams.of(data) - byte[] signature = Jwts.SIG.RS256.digest(new DefaultSecureRequest<>(payload, provider, null, pair.getPrivate())) + byte[] signature = Jws.alg.RS256.digest(new DefaultSecureRequest<>(payload, provider, null, pair.getPrivate())) payload.reset() - assertTrue Jwts.SIG.RS256.verify(new DefaultVerifySecureDigestRequest(payload, provider, null, pair.getPublic(), signature)) + assertTrue Jws.alg.RS256.verify(new DefaultVerifySecureDigestRequest(payload, provider, null, pair.getPublic(), signature)) } @Test void testSignFailsWithAnExternalException() { - def pair = Jwts.SIG.RS256.keyPair().build() + def pair = Jws.alg.RS256.keyPair().build() def ise = new IllegalStateException('foo') def alg = new TestAbstractSecureDigestAlgorithm() { @Override @@ -66,7 +66,7 @@ class AbstractSecureDigestAlgorithmTest { @Test void testVerifyFailsWithExternalException() { - def pair = Jwts.SIG.RS256.keyPair().build() + def pair = Jws.alg.RS256.keyPair().build() def ise = new IllegalStateException('foo') def alg = new TestAbstractSecureDigestAlgorithm() { @Override diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/security/AesGcmKeyAlgorithmTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/security/AesGcmKeyAlgorithmTest.groovy index 54f444b1a..46ab9cad1 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/security/AesGcmKeyAlgorithmTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/security/AesGcmKeyAlgorithmTest.groovy @@ -15,6 +15,7 @@ */ package io.jsonwebtoken.impl.security +import io.jsonwebtoken.Jwe import io.jsonwebtoken.JweHeader import io.jsonwebtoken.Jwts import io.jsonwebtoken.MalformedJwtException @@ -72,7 +73,7 @@ class AesGcmKeyAlgorithmTest { def out = new ByteArrayOutputStream(8192) def encRequest = new DefaultAeadRequest(Streams.of(cek.getEncoded()), null, null, kek, null, iv) def encResult = new DefaultAeadResult(out) - Jwts.ENC.A256GCM.encrypt(encRequest, encResult) + Jwe.alg.A256GCM.encrypt(encRequest, encResult) assertArrayEquals tag, encResult.digest assertArrayEquals iv, encResult.iv diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/security/DefaultMacAlgorithmTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/security/DefaultMacAlgorithmTest.groovy index 6df8d95b7..43d1ba7ee 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/security/DefaultMacAlgorithmTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/security/DefaultMacAlgorithmTest.groovy @@ -149,7 +149,7 @@ class DefaultMacAlgorithmTest { String msg = 'The signing key\'s size is 192 bits which is not secure enough for the HS256 algorithm. ' + 'The JWT JWA Specification (RFC 7518, Section 3.2) states that keys used with HS256 MUST have a ' + 'size >= 256 bits (the key size must be greater than or equal to the hash output size). ' + - 'Consider using the Jwts.SIG.HS256.key() builder to create a key guaranteed ' + + 'Consider using the Jws.alg.HS256.key() builder to create a key guaranteed ' + 'to be secure enough for HS256. See https://tools.ietf.org/html/rfc7518#section-3.2 for more ' + 'information.' assertEquals msg, expected.getMessage() diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/security/DefaultRsaKeyAlgorithmTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/security/DefaultRsaKeyAlgorithmTest.groovy index 4541463b1..315ac8467 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/security/DefaultRsaKeyAlgorithmTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/security/DefaultRsaKeyAlgorithmTest.groovy @@ -15,7 +15,7 @@ */ package io.jsonwebtoken.impl.security -import io.jsonwebtoken.Jwts +import io.jsonwebtoken.Jwe import io.jsonwebtoken.security.InvalidKeyException import io.jsonwebtoken.security.WeakKeyException import org.junit.Test @@ -29,11 +29,11 @@ import static org.junit.Assert.assertEquals class DefaultRsaKeyAlgorithmTest { - static final algs = [Jwts.KEY.RSA1_5, Jwts.KEY.RSA_OAEP, Jwts.KEY.RSA_OAEP_256] as List + static final algs = [Jwe.enc.RSA1_5, Jwe.enc.RSA_OAEP, Jwe.enc.RSA_OAEP_256] as List @Test void testValidateNonRSAKey() { - SecretKey key = Jwts.KEY.A128KW.key().build() + SecretKey key = Jwe.enc.A128KW.key().build() for (DefaultRsaKeyAlgorithm alg : algs) { try { alg.validate(key, true) diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/security/DirectKeyAlgorithmTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/security/DirectKeyAlgorithmTest.groovy index 82a2c08a1..a82a1dd14 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/security/DirectKeyAlgorithmTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/security/DirectKeyAlgorithmTest.groovy @@ -15,7 +15,7 @@ */ package io.jsonwebtoken.impl.security -import io.jsonwebtoken.Jwts +import io.jsonwebtoken.Jwe import io.jsonwebtoken.impl.DefaultJweHeader import io.jsonwebtoken.lang.Arrays import io.jsonwebtoken.security.DecryptionKeyRequest @@ -39,7 +39,7 @@ class DirectKeyAlgorithmTest { void testGetEncryptionKey() { def alg = new DirectKeyAlgorithm() def key = new SecretKeySpec(new byte[1], "AES") - def request = new DefaultKeyRequest(key, null, null, new DefaultJweHeader([:]), Jwts.ENC.A128GCM) + def request = new DefaultKeyRequest(key, null, null, new DefaultJweHeader([:]), Jwe.alg.A128GCM) def result = alg.getEncryptionKey(request) assertSame key, result.getKey() assertEquals 0, Arrays.length(result.getPayload()) //must not have an encrypted key @@ -53,7 +53,7 @@ class DirectKeyAlgorithmTest { @Test(expected = IllegalArgumentException) void testGetEncryptionKeyWithNullRequestKey() { def key = new SecretKeySpec(new byte[1], "AES") - def request = new DefaultKeyRequest(key, null, null, new DefaultJweHeader([:]), Jwts.ENC.A128GCM) { + def request = new DefaultKeyRequest(key, null, null, new DefaultJweHeader([:]), Jwe.alg.A128GCM) { @Override Key getPayload() { return null @@ -66,7 +66,7 @@ class DirectKeyAlgorithmTest { void testGetDecryptionKey() { def alg = new DirectKeyAlgorithm() DecryptionKeyRequest req = createMock(DecryptionKeyRequest) - def key = Jwts.ENC.A128GCM.key().build() + def key = Jwe.alg.A128GCM.key().build() expect(req.getKey()).andReturn(key) replay(req) def result = alg.getDecryptionKey(req) diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/security/EcPrivateJwkFactoryTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/security/EcPrivateJwkFactoryTest.groovy index f599fc5bb..5b4654336 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/security/EcPrivateJwkFactoryTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/security/EcPrivateJwkFactoryTest.groovy @@ -15,7 +15,7 @@ */ package io.jsonwebtoken.impl.security -import io.jsonwebtoken.Jwts +import io.jsonwebtoken.Jws import io.jsonwebtoken.security.InvalidKeyException import io.jsonwebtoken.security.MalformedKeyException import org.junit.Test @@ -48,7 +48,7 @@ class EcPrivateJwkFactoryTest { @Test void testDerivePublicFails() { - def pair = Jwts.SIG.ES256.keyPair().build() + def pair = Jws.alg.ES256.keyPair().build() def priv = pair.getPrivate() as ECPrivateKey final def context = new DefaultJwkContext(DefaultEcPrivateJwk.PARAMS) diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/security/EcSignatureAlgorithmTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/security/EcSignatureAlgorithmTest.groovy index a4993bc27..b0ac549c8 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/security/EcSignatureAlgorithmTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/security/EcSignatureAlgorithmTest.groovy @@ -16,8 +16,8 @@ //file:noinspection SpellCheckingInspection package io.jsonwebtoken.impl.security +import io.jsonwebtoken.Jws import io.jsonwebtoken.JwtException -import io.jsonwebtoken.Jwts import io.jsonwebtoken.impl.io.Streams import io.jsonwebtoken.impl.lang.Bytes import io.jsonwebtoken.io.Decoders @@ -44,7 +44,7 @@ import static org.junit.Assert.* class EcSignatureAlgorithmTest { static Collection algs() { - return Jwts.SIG.get().values().findAll({ it instanceof EcSignatureAlgorithm }) as Collection + return Jws.alg.registry().values().findAll({ it instanceof EcSignatureAlgorithm }) as Collection } @Test @@ -121,7 +121,7 @@ class EcSignatureAlgorithmTest { void testSignWithPublicKey() { ECPublicKey key = TestKeys.ES256.pair.public as ECPublicKey def request = new DefaultSecureRequest(Streams.of(new byte[1]), null, null, key) - def alg = Jwts.SIG.ES256 + def alg = Jws.alg.ES256 try { alg.digest(request) } catch (InvalidKeyException e) { @@ -152,11 +152,11 @@ class EcSignatureAlgorithmTest { @Test void testSignWithInvalidKeyFieldLength() { - def keypair = Jwts.SIG.ES256.keyPair().build() + def keypair = Jws.alg.ES256.keyPair().build() def data = "foo".getBytes(StandardCharsets.UTF_8) def req = new DefaultSecureRequest(Streams.of(data), null, null, keypair.private) try { - Jwts.SIG.ES384.digest(req) + Jws.alg.ES384.digest(req) } catch (InvalidKeyException expected) { String msg = "The provided Elliptic Curve signing key size (aka order bit length) is " + "256 bits (32 bytes), but the 'ES384' algorithm requires EC Keys with " + @@ -305,7 +305,7 @@ class EcSignatureAlgorithmTest { def fact = KeyFactory.getInstance("EC") def publicKey = "MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQASisgweVL1tAtIvfmpoqvdXF8sPKTV9YTKNxBwkdkm+/auh4pR8TbaIfsEzcsGUVv61DFNFXb0ozJfurQ59G2XcgAn3vROlSSnpbIvuhKrzL5jwWDTaYa5tVF1Zjwia/5HUhKBkcPuWGXg05nMjWhZfCuEetzMLoGcHmtvabugFrqsAg=" def pub = fact.generatePublic(new X509EncodedKeySpec(Decoders.BASE64.decode(publicKey))) - def alg = Jwts.SIG.ES512 + def alg = Jws.alg.ES512 def verifier = { String token -> def signatureStart = token.lastIndexOf('.') def withoutSignature = token.substring(0, signatureStart) @@ -466,7 +466,7 @@ class EcSignatureAlgorithmTest { def fact = KeyFactory.getInstance("EC") def publicKey = "MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQASisgweVL1tAtIvfmpoqvdXF8sPKTV9YTKNxBwkdkm+/auh4pR8TbaIfsEzcsGUVv61DFNFXb0ozJfurQ59G2XcgAn3vROlSSnpbIvuhKrzL5jwWDTaYa5tVF1Zjwia/5HUhKBkcPuWGXg05nMjWhZfCuEetzMLoGcHmtvabugFrqsAg=" def pub = fact.generatePublic(new X509EncodedKeySpec(Decoders.BASE64.decode(publicKey))) - def alg = Jwts.SIG.ES512 + def alg = Jws.alg.ES512 def verifier = { String token -> def signatureStart = token.lastIndexOf('.') def withoutSignature = token.substring(0, signatureStart) @@ -488,7 +488,7 @@ class EcSignatureAlgorithmTest { // asserts guard for JVM security bug CVE-2022-21449: void legacySignatureCompatDefaultTest() { def withoutSignature = "eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCJ9.eyJ0ZXN0IjoidGVzdCIsImlhdCI6MTQ2NzA2NTgyN30" - def alg = Jwts.SIG.ES512 + def alg = Jws.alg.ES512 def keypair = alg.keyPair().build() def signature = Signature.getInstance(alg.jcaName as String) def data = Strings.ascii(withoutSignature) @@ -515,7 +515,7 @@ class EcSignatureAlgorithmTest { System.setProperty(EcSignatureAlgorithm.DER_ENCODING_SYS_PROPERTY_NAME, 'true') def withoutSignature = "eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCJ9.eyJ0ZXN0IjoidGVzdCIsImlhdCI6MTQ2NzA2NTgyN30" - def alg = Jwts.SIG.ES512 + def alg = Jws.alg.ES512 def keypair = alg.keyPair().build() def signature = Signature.getInstance(alg.jcaName as String) def data = Strings.ascii(withoutSignature) @@ -535,7 +535,7 @@ class EcSignatureAlgorithmTest { void testVerifySignatureAllZeros() { byte[] forgedSig = new byte[64] def withoutSignature = "eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCJ9.eyJ0ZXN0IjoidGVzdCIsImlhdCI6MTQ2NzA2NTgyN30" - def alg = Jwts.SIG.ES256 + def alg = Jws.alg.ES256 def keypair = alg.keyPair().build() def data = Strings.ascii(withoutSignature) def payload = Streams.of(data) @@ -553,7 +553,7 @@ class EcSignatureAlgorithmTest { System.arraycopy(s, 0, sig, r.length, s.length) def withoutSignature = "eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCJ9.eyJ0ZXN0IjoidGVzdCIsImlhdCI6MTQ2NzA2NTgyN30" - def alg = Jwts.SIG.ES256 + def alg = Jws.alg.ES256 def keypair = alg.keyPair().build() def data = Strings.ascii(withoutSignature) def payload = Streams.of(data) @@ -571,7 +571,7 @@ class EcSignatureAlgorithmTest { System.arraycopy(s, 0, sig, r.length, s.length) def withoutSignature = "eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCJ9.eyJ0ZXN0IjoidGVzdCIsImlhdCI6MTQ2NzA2NTgyN30" - def alg = Jwts.SIG.ES256 + def alg = Jws.alg.ES256 def keypair = alg.keyPair().build() def data = Strings.ascii(withoutSignature) def payload = Streams.of(data) @@ -584,7 +584,7 @@ class EcSignatureAlgorithmTest { void ecdsaInvalidSignatureValuesTest() { def withoutSignature = "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZXN0IjoidGVzdCIsImlhdCI6MTQ2NzA2NTgyN30" def invalidEncodedSignature = "_____wAAAAD__________7zm-q2nF56E87nKwvxjJVH_____AAAAAP__________vOb6racXnoTzucrC_GMlUQ" - def alg = Jwts.SIG.ES256 + def alg = Jws.alg.ES256 def keypair = alg.keyPair().build() def data = Strings.ascii(withoutSignature) def payload = Streams.of(data) diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/security/EcdhKeyAlgorithmTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/security/EcdhKeyAlgorithmTest.groovy index 00907b426..0d63f5562 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/security/EcdhKeyAlgorithmTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/security/EcdhKeyAlgorithmTest.groovy @@ -15,6 +15,7 @@ */ package io.jsonwebtoken.impl.security +import io.jsonwebtoken.Jwe import io.jsonwebtoken.JweHeader import io.jsonwebtoken.Jwts import io.jsonwebtoken.MalformedJwtException @@ -49,7 +50,7 @@ class EcdhKeyAlgorithmTest { PublicKey encKey = TestKeys.X25519.pair.public as PublicKey def header = new DefaultMutableJweHeader(Jwts.header()) def provider = TestKeys.BC - def request = new DefaultKeyRequest(encKey, provider, null, header, Jwts.ENC.A128GCM) + def request = new DefaultKeyRequest(encKey, provider, null, header, Jwe.alg.A128GCM) def result = alg.getEncryptionKey(request) assertNotNull result.getKey() } @@ -57,7 +58,7 @@ class EcdhKeyAlgorithmTest { @Test void testEdwardsDecryptionWithRequestProvider() { def alg = new EcdhKeyAlgorithm() - def enc = Jwts.ENC.A128GCM + def enc = Jwe.alg.A128GCM PublicKey encKey = TestKeys.X25519.pair.public as PublicKey PrivateKey decKey = TestKeys.X25519.pair.private as PrivateKey def header = jwe() @@ -85,7 +86,7 @@ class EcdhKeyAlgorithmTest { def header = new DefaultJweHeader([:]) - DecryptionKeyRequest req = new DefaultDecryptionKeyRequest('test'.getBytes(), null, null, header, Jwts.ENC.A128GCM, decryptionKey) + DecryptionKeyRequest req = new DefaultDecryptionKeyRequest('test'.getBytes(), null, null, header, Jwe.alg.A128GCM, decryptionKey) try { alg.getDecryptionKey(req) @@ -106,7 +107,7 @@ class EcdhKeyAlgorithmTest { def jwk = Jwks.builder().key(TestKeys.ES384.pair.public as ECPublicKey).build() JweHeader header = jwe().add('epk', jwk).build() as JweHeader - DecryptionKeyRequest req = new DefaultDecryptionKeyRequest('test'.getBytes(), null, null, header, Jwts.ENC.A128GCM, decryptionKey) + DecryptionKeyRequest req = new DefaultDecryptionKeyRequest('test'.getBytes(), null, null, header, Jwe.alg.A128GCM, decryptionKey) try { alg.getDecryptionKey(req) @@ -124,7 +125,7 @@ class EcdhKeyAlgorithmTest { def alg = new EcdhKeyAlgorithm() PublicKey encKey = TestKeys.RS256.pair.public as PublicKey // not an elliptic curve key, must fail def header = new DefaultMutableJweHeader(Jwts.header()) - def request = new DefaultKeyRequest(encKey, null, null, header, Jwts.ENC.A128GCM) + def request = new DefaultKeyRequest(encKey, null, null, header, Jwe.alg.A128GCM) try { alg.getEncryptionKey(request) fail() @@ -140,7 +141,7 @@ class EcdhKeyAlgorithmTest { PrivateKey key = TestKeys.RS256.pair.private as PrivateKey // not an elliptic curve key, must fail def jwk = Jwks.builder().key(TestKeys.RS256.pair.public as RSAPublicKey).build() JweHeader header = jwe().add('epk', jwk).build() as JweHeader - def request = new DefaultDecryptionKeyRequest('test'.getBytes(), null, null, header, Jwts.ENC.A128GCM, key) + def request = new DefaultDecryptionKeyRequest('test'.getBytes(), null, null, header, Jwe.alg.A128GCM, key) try { alg.getDecryptionKey(request) fail() @@ -155,7 +156,7 @@ class EcdhKeyAlgorithmTest { def alg = new EcdhKeyAlgorithm() PrivateKey key = TestKeys.ES256.pair.private as PrivateKey // valid key def header = new DefaultJweHeader([:]) // no 'epk' value - def request = new DefaultDecryptionKeyRequest('test'.getBytes(), null, null, header, Jwts.ENC.A128GCM, key) + def request = new DefaultDecryptionKeyRequest('test'.getBytes(), null, null, header, Jwe.alg.A128GCM, key) try { alg.getDecryptionKey(request) fail() @@ -171,7 +172,7 @@ class EcdhKeyAlgorithmTest { PrivateKey key = TestKeys.ES256.pair.private as PrivateKey // valid key def jwk = Jwks.builder().key(TestKeys.RS256.pair.public as RSAPublicKey).build() // invalid epk JweHeader header = jwe().add('epk', jwk).build() as JweHeader - def request = new DefaultDecryptionKeyRequest('test'.getBytes(), null, null, header, Jwts.ENC.A128GCM, key) + def request = new DefaultDecryptionKeyRequest('test'.getBytes(), null, null, header, Jwe.alg.A128GCM, key) try { alg.getDecryptionKey(request) fail() @@ -187,7 +188,7 @@ class EcdhKeyAlgorithmTest { PrivateKey key = TestKeys.X25519.pair.private as PrivateKey // valid key def jwk = Jwks.builder().key(TestKeys.RS256.pair.public as RSAPublicKey).build() // invalid epk JweHeader header = jwe().add('epk', jwk).build() as JweHeader - def request = new DefaultDecryptionKeyRequest('test'.getBytes(), null, null, header, Jwts.ENC.A128GCM, key) + def request = new DefaultDecryptionKeyRequest('test'.getBytes(), null, null, header, Jwe.alg.A128GCM, key) try { alg.getDecryptionKey(request) fail() @@ -203,7 +204,7 @@ class EcdhKeyAlgorithmTest { PrivateKey key = TestKeys.X25519.pair.private as PrivateKey // valid key def jwk = Jwks.builder().key(TestKeys.X448.pair.public as PublicKey).build() // epk is not on X25519 JweHeader header = jwe().add('epk', jwk).build() as JweHeader - def request = new DefaultDecryptionKeyRequest('test'.getBytes(), null, null, header, Jwts.ENC.A128GCM, key) + def request = new DefaultDecryptionKeyRequest('test'.getBytes(), null, null, header, Jwe.alg.A128GCM, key) try { alg.getDecryptionKey(request) fail() diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/security/EdSignatureAlgorithmTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/security/EdSignatureAlgorithmTest.groovy index a7c9b9848..cb8db348a 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/security/EdSignatureAlgorithmTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/security/EdSignatureAlgorithmTest.groovy @@ -15,6 +15,7 @@ */ package io.jsonwebtoken.impl.security +import io.jsonwebtoken.Jws import io.jsonwebtoken.Jwts import io.jsonwebtoken.UnsupportedJwtException import io.jsonwebtoken.security.SignatureException @@ -27,7 +28,7 @@ import static org.junit.Assert.* class EdSignatureAlgorithmTest { - static EdSignatureAlgorithm alg = Jwts.SIG.EdDSA as EdSignatureAlgorithm + static EdSignatureAlgorithm alg = Jws.alg.EdDSA as EdSignatureAlgorithm @Test void testJcaName() { diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/security/EdwardsPublicKeyDeriverTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/security/EdwardsPublicKeyDeriverTest.groovy index 0d931b667..9803dc5ae 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/security/EdwardsPublicKeyDeriverTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/security/EdwardsPublicKeyDeriverTest.groovy @@ -15,7 +15,7 @@ */ package io.jsonwebtoken.impl.security -import io.jsonwebtoken.Jwts +import io.jsonwebtoken.Jws import io.jsonwebtoken.security.InvalidKeyException import org.junit.Test @@ -26,7 +26,7 @@ class EdwardsPublicKeyDeriverTest { @Test void testDeriveWithNonEdwardsKey() { - def rsaPrivKey = Jwts.SIG.RS256.keyPair().build().getPrivate() + def rsaPrivKey = Jws.alg.RS256.keyPair().build().getPrivate() try { EdwardsPublicKeyDeriver.INSTANCE.apply(rsaPrivKey) fail() diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/security/GcmAesAeadAlgorithmTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/security/GcmAesAeadAlgorithmTest.groovy index 04264341a..ab5f4c0cf 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/security/GcmAesAeadAlgorithmTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/security/GcmAesAeadAlgorithmTest.groovy @@ -15,7 +15,7 @@ */ package io.jsonwebtoken.impl.security -import io.jsonwebtoken.Jwts +import io.jsonwebtoken.Jwe import io.jsonwebtoken.impl.io.Streams import org.junit.Test @@ -58,7 +58,7 @@ class GcmAesAeadAlgorithmTest { @Test void testEncryptionAndDecryption() { - def alg = Jwts.ENC.A256GCM + def alg = Jwe.alg.A256GCM def ins = Streams.of(P) def aad = Streams.of(AAD) diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/security/HmacAesAeadAlgorithmTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/security/HmacAesAeadAlgorithmTest.groovy index 4c0bd0935..5cfbc89a2 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/security/HmacAesAeadAlgorithmTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/security/HmacAesAeadAlgorithmTest.groovy @@ -15,7 +15,7 @@ */ package io.jsonwebtoken.impl.security -import io.jsonwebtoken.Jwts +import io.jsonwebtoken.Jwe import io.jsonwebtoken.impl.io.Streams import io.jsonwebtoken.impl.lang.Bytes import io.jsonwebtoken.lang.Strings @@ -37,17 +37,17 @@ class HmacAesAeadAlgorithmTest { // asserts that key lengths are double than what is usually expected for AES // due to the encrypt-then-mac scheme requiring two separate keys // (encrypt key is half of the generated key, mac key is the 2nd half of the generated key): - assertEquals 256, Jwts.ENC.A128CBC_HS256.getKeyBitLength() - assertEquals 384, Jwts.ENC.A192CBC_HS384.getKeyBitLength() - assertEquals 512, Jwts.ENC.A256CBC_HS512.getKeyBitLength() + assertEquals 256, Jwe.alg.A128CBC_HS256.getKeyBitLength() + assertEquals 384, Jwe.alg.A192CBC_HS384.getKeyBitLength() + assertEquals 512, Jwe.alg.A256CBC_HS512.getKeyBitLength() } @Test void testGenerateKey() { def algs = [ - Jwts.ENC.A128CBC_HS256, - Jwts.ENC.A192CBC_HS384, - Jwts.ENC.A256CBC_HS512 + Jwe.alg.A128CBC_HS256, + Jwe.alg.A192CBC_HS384, + Jwe.alg.A256CBC_HS512 ] for (AeadAlgorithm alg : algs) { SecretKey key = alg.key().build() @@ -58,7 +58,7 @@ class HmacAesAeadAlgorithmTest { @Test(expected = SignatureException) void testDecryptWithInvalidTag() { - def alg = Jwts.ENC.A128CBC_HS256 + def alg = Jwe.alg.A128CBC_HS256 SecretKey key = alg.key().build() diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/security/JwksTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/security/JwksTest.groovy index 30d8d43ef..109b14ed8 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/security/JwksTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/security/JwksTest.groovy @@ -15,7 +15,7 @@ */ package io.jsonwebtoken.impl.security -import io.jsonwebtoken.Jwts +import io.jsonwebtoken.Jws import io.jsonwebtoken.impl.lang.Converters import io.jsonwebtoken.io.Decoders import io.jsonwebtoken.io.Encoders @@ -41,7 +41,7 @@ import static org.junit.Assert.* class JwksTest { private static final SecretKey SKEY = TestKeys.NA256 - private static final java.security.KeyPair EC_PAIR = Jwts.SIG.ES256.keyPair().build() + private static final java.security.KeyPair EC_PAIR = Jws.alg.ES256.keyPair().build() private static String srandom() { byte[] random = new byte[16] @@ -197,7 +197,7 @@ class JwksTest { @Test void testX509CertChain() { //get a test cert: - X509Certificate cert = TestKeys.forAlgorithm(Jwts.SIG.RS256).cert + X509Certificate cert = TestKeys.forAlgorithm(Jws.alg.RS256).cert def sval = JwtX509StringConverter.INSTANCE.applyTo(cert) testProperty('x509Chain', 'x5c', [cert], [sval]) } @@ -225,7 +225,7 @@ class JwksTest { } static void testX509Thumbprint(int number) { - def algs = Jwts.SIG.get().values().findAll { it instanceof SignatureAlgorithm } + def algs = Jws.alg.registry().values().findAll { it instanceof SignatureAlgorithm } for (def alg : algs) { //get test cert: @@ -248,7 +248,7 @@ class JwksTest { @Test void testSecretJwks() { - Collection algs = Jwts.SIG.get().values().findAll({ it instanceof MacAlgorithm }) as Collection + Collection algs = Jws.alg.registry().values().findAll({ it instanceof MacAlgorithm }) as Collection for (def alg : algs) { SecretKey secretKey = alg.key().build() def jwk = Jwks.builder().key(secretKey).id('id').build() @@ -300,7 +300,7 @@ class JwksTest { @Test void testAsymmetricJwks() { - Collection algs = Jwts.SIG.get().values() + Collection algs = Jws.alg.registry().values() .findAll({ it instanceof SignatureAlgorithm }) as Collection for (SignatureAlgorithm alg : algs) { @@ -345,7 +345,7 @@ class JwksTest { @Test void testInvalidEcCurvePoint() { - def algs = [Jwts.SIG.ES256, Jwts.SIG.ES384, Jwts.SIG.ES512] + def algs = [Jws.alg.ES256, Jws.alg.ES384, Jws.alg.ES512] for (SignatureAlgorithm alg : algs) { diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/security/KeyPairsTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/security/KeyPairsTest.groovy index 3f8ab28a1..b8644e49a 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/security/KeyPairsTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/security/KeyPairsTest.groovy @@ -15,7 +15,7 @@ */ package io.jsonwebtoken.impl.security -import io.jsonwebtoken.Jwts +import io.jsonwebtoken.Jws import org.junit.Test import java.security.Key @@ -62,7 +62,7 @@ class KeyPairsTest { @Test void testGetKeyECMismatch() { - KeyPair pair = Jwts.SIG.RS256.keyPair().build() + KeyPair pair = Jws.alg.RS256.keyPair().build() Class clazz = ECPublicKey try { KeyPairs.getKey(pair, clazz) diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/security/Pbes2HsAkwAlgorithmTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/security/Pbes2HsAkwAlgorithmTest.groovy index 242308bf3..73fb04dd0 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/security/Pbes2HsAkwAlgorithmTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/security/Pbes2HsAkwAlgorithmTest.groovy @@ -15,6 +15,7 @@ */ package io.jsonwebtoken.impl.security +import io.jsonwebtoken.Jwe import io.jsonwebtoken.Jwts import io.jsonwebtoken.UnsupportedJwtException import io.jsonwebtoken.impl.DefaultJweHeaderMutator @@ -33,9 +34,9 @@ import static org.junit.Assert.fail class Pbes2HsAkwAlgorithmTest { private static Password KEY = Keys.password("12345678".toCharArray()) - private static List ALGS = [Jwts.KEY.PBES2_HS256_A128KW, - Jwts.KEY.PBES2_HS384_A192KW, - Jwts.KEY.PBES2_HS512_A256KW] as List + private static List ALGS = [Jwe.enc.PBES2_HS256_A128KW, + Jwe.enc.PBES2_HS384_A192KW, + Jwe.enc.PBES2_HS512_A256KW] as List @Test void testInsufficientIterations() { @@ -43,7 +44,7 @@ class Pbes2HsAkwAlgorithmTest { int iterations = 50 // must be 1000 or more def header = Jwts.header().pbes2Count(iterations) as DefaultJweHeaderMutator def mutable = new DefaultMutableJweHeader(header) - KeyRequest req = new DefaultKeyRequest<>(KEY, null, null, mutable, Jwts.ENC.A256GCM) + KeyRequest req = new DefaultKeyRequest<>(KEY, null, null, mutable, Jwe.alg.A256GCM) try { alg.getEncryptionKey(req) fail() @@ -91,10 +92,10 @@ class Pbes2HsAkwAlgorithmTest { @Test void test() { - def alg = Jwts.KEY.PBES2_HS256_A128KW + def alg = Jwe.enc.PBES2_HS256_A128KW int desiredMillis = 100 - int iterations = Jwts.KEY.estimateIterations(alg, desiredMillis) + int iterations = Jwe.enc.estimateIterations(alg, desiredMillis) println "Estimated iterations: $iterations" int tries = 30 @@ -104,7 +105,7 @@ class Pbes2HsAkwAlgorithmTest { def password = 'hellowor'.toCharArray() def header = new DefaultJweHeader().pbes2Count(iterations) def key = Keys.password(password) - def req = new DefaultKeyRequest(null, null, key, header, Jwts.ENC.A128GCM) + def req = new DefaultKeyRequest(null, null, key, header, Jwe.alg.A128GCM) int sum = 0 for (int i = 0; i < tries; i++) { long start = System.currentTimeMillis() diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/security/Pkcs11Test.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/security/Pkcs11Test.groovy index da442934f..65a7d4a77 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/security/Pkcs11Test.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/security/Pkcs11Test.groovy @@ -16,6 +16,8 @@ package io.jsonwebtoken.impl.security import io.jsonwebtoken.Identifiable +import io.jsonwebtoken.Jwe +import io.jsonwebtoken.Jws import io.jsonwebtoken.Jwts import io.jsonwebtoken.impl.lang.Bytes import io.jsonwebtoken.lang.Assert @@ -116,8 +118,8 @@ class Pkcs11Test { def prot = new KeyStore.PasswordProtection(PIN) def algs = [] as List - algs.addAll(Jwts.SIG.get().values().findAll({ it instanceof KeyBuilderSupplier })) - algs.addAll(Jwts.ENC.get().values()) + algs.addAll(Jws.alg.registry().values().findAll({ it instanceof KeyBuilderSupplier })) + algs.addAll(Jwe.alg.registry().values()) algs.each { Identifiable alg -> // find any previous one: @@ -149,7 +151,7 @@ class Pkcs11Test { Map bundles = new LinkedHashMap() def algs = [] - algs.addAll(Jwts.SIG.get().values().findAll({ + algs.addAll(Jws.alg.registry().values().findAll({ it instanceof KeyPairBuilderSupplier && it.id != 'EdDSA' })) algs.addAll(Jwks.CRV.get().values().findAll({ it instanceof EdwardsCurve })) @@ -210,7 +212,7 @@ class Pkcs11Test { static void testJws(Provider keyProvider) { def algs = [] as List - algs.addAll(Jwts.SIG.get().values().findAll({ it != Jwts.SIG.EdDSA })) // EdDSA accounted for by next two: + algs.addAll(Jws.alg.registry().values().findAll({ it != Jws.alg.EdDSA })) // EdDSA accounted for by next two: algs.add(Jwks.CRV.Ed25519) algs.add(Jwks.CRV.Ed448) @@ -225,7 +227,7 @@ class Pkcs11Test { } if (!signKey) continue // not supported by Either the SunPKCS11 provider or SoftHSM2, so we have to try next - alg = alg instanceof Curve ? Jwts.SIG.EdDSA : alg as SecureDigestAlgorithm + alg = alg instanceof Curve ? Jws.alg.EdDSA : alg as SecureDigestAlgorithm // We might need to specify the PKCS11 provider since we can't access the private key material: def jws = Jwts.builder().provider(keyProvider).issuer('me').signWith(signKey, alg).compact() @@ -270,7 +272,7 @@ class Pkcs11Test { } // Encryption uses the public key, and that key material is available, so no need for the PKCS11 provider: - String jwe = Jwts.builder().issuer('me').encryptWith(pub, keyalg, Jwts.ENC.A256GCM).compact() + String jwe = Jwts.builder().issuer('me').encryptWith(pub, keyalg, Jwe.alg.A256GCM).compact() // The private key can be null if SunPKCS11 doesn't support the key algorithm directly. In this case // encryption only worked because generic X.509 decoding (from the key certificate in the keystore) produced the @@ -286,7 +288,7 @@ class Pkcs11Test { static void testJwe(Provider provider) { def algs = [] - algs.addAll(Jwts.SIG.get().values().findAll({ + algs.addAll(Jws.alg.registry().values().findAll({ it.id.startsWith('RS') || it.id.startsWith('ES') // unfortunately we can't also match .startsWith('PS') because SoftHSM2 doesn't support RSA-PSS keys :( // see https://github.com/opendnssec/SoftHSMv2/issues/721 @@ -306,10 +308,10 @@ class Pkcs11Test { if (name == 'RSA') { // SunPKCS11 doesn't support RSA-OAEP* ciphers :( // So we can only try with RSA1_5 and we have to skip RSA_OAEP and RSA_OAEP_256: - encRoundtrip(bundle, Jwts.KEY.RSA1_5, provider) + encRoundtrip(bundle, Jwe.enc.RSA1_5, provider) } else if (StandardCurves.findByKey(bundle.pair.public) != null) { // EC or Ed key // try all ECDH key algorithms: - Jwts.KEY.get().values().findAll({ it.id.startsWith('ECDH-ES') }).each { + Jwe.enc.registry().values().findAll({ it.id.startsWith('ECDH-ES') }).each { encRoundtrip(bundle, it, provider) } } else { diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/security/PrivateConstructorsTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/security/PrivateConstructorsTest.groovy index d60e8b2e8..6ecdd9a76 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/security/PrivateConstructorsTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/security/PrivateConstructorsTest.groovy @@ -15,6 +15,8 @@ */ package io.jsonwebtoken.impl.security +import io.jsonwebtoken.Jwe +import io.jsonwebtoken.Jws import io.jsonwebtoken.Jwts import io.jsonwebtoken.impl.lang.Functions import io.jsonwebtoken.lang.Classes @@ -22,6 +24,8 @@ import io.jsonwebtoken.security.Jwks import io.jsonwebtoken.security.Suppliers import org.junit.Test +import static org.junit.Assert.assertSame + class PrivateConstructorsTest { @Test @@ -30,9 +34,12 @@ class PrivateConstructorsTest { new KeysBridge() new JwksBridge() new Functions() - new Jwts.SIG() - new Jwts.ENC() - new Jwts.KEY() + new Jws.alg() + new Jwe.alg() + new Jwe.enc() + new Jwts.SIG(); assertSame(Jws.alg.registry(), Jwts.SIG.get()) + new Jwts.ENC(); assertSame(Jwe.alg.registry(), Jwts.ENC.get()) + new Jwts.KEY(); assertSame(Jwe.enc.registry(), Jwts.KEY.get()) new Jwts.ZIP() new Jwks.CRV() new Jwks.HASH() diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/security/RFC7516AppendixA3Test.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/security/RFC7516AppendixA3Test.groovy index f4c74188d..b7b026f23 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/security/RFC7516AppendixA3Test.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/security/RFC7516AppendixA3Test.groovy @@ -128,7 +128,7 @@ class RFC7516AppendixA3Test { String compact = Jwts.builder() .setPayload(PLAINTEXT) - .encryptWith(kek, Jwts.KEY.A128KW, enc) + .encryptWith(kek, Jwe.enc.A128KW, enc) .compact() assertEquals COMPLETE_JWE, compact diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/security/RFC7518AppendixB1Test.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/security/RFC7518AppendixB1Test.groovy index 246b82871..74c76759d 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/security/RFC7518AppendixB1Test.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/security/RFC7518AppendixB1Test.groovy @@ -15,7 +15,7 @@ */ package io.jsonwebtoken.impl.security -import io.jsonwebtoken.Jwts +import io.jsonwebtoken.Jwe import io.jsonwebtoken.impl.io.Streams import org.junit.Test @@ -88,7 +88,7 @@ class RFC7518AppendixB1Test { @Test void test() { - def alg = Jwts.ENC.A128CBC_HS256 + def alg = Jwe.alg.A128CBC_HS256 def aad = Streams.of(A) def out = new ByteArrayOutputStream(8192) def result = new DefaultAeadResult(out) diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/security/RFC7518AppendixB2Test.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/security/RFC7518AppendixB2Test.groovy index 8272af884..fe349cacc 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/security/RFC7518AppendixB2Test.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/security/RFC7518AppendixB2Test.groovy @@ -15,7 +15,7 @@ */ package io.jsonwebtoken.impl.security -import io.jsonwebtoken.Jwts +import io.jsonwebtoken.Jwe import io.jsonwebtoken.impl.io.Streams import io.jsonwebtoken.security.AeadRequest import org.junit.Test @@ -84,7 +84,7 @@ class RFC7518AppendixB2Test { @Test void test() { - def alg = Jwts.ENC.A192CBC_HS384 + def alg = Jwe.alg.A192CBC_HS384 def aad = Streams.of(A) def out = new ByteArrayOutputStream(8192) def result = new DefaultAeadResult(out) diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/security/RFC7518AppendixB3Test.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/security/RFC7518AppendixB3Test.groovy index 80fff053b..985637674 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/security/RFC7518AppendixB3Test.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/security/RFC7518AppendixB3Test.groovy @@ -15,7 +15,7 @@ */ package io.jsonwebtoken.impl.security -import io.jsonwebtoken.Jwts +import io.jsonwebtoken.Jwe import io.jsonwebtoken.impl.io.Streams import io.jsonwebtoken.security.AeadRequest import org.junit.Test @@ -86,7 +86,7 @@ class RFC7518AppendixB3Test { @Test void test() { - def alg = Jwts.ENC.A256CBC_HS512 + def alg = Jwe.alg.A256CBC_HS512 def aad = Streams.of(A) def out = new ByteArrayOutputStream(8192) def res = new DefaultAeadResult(out) diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/security/RFC7518AppendixCTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/security/RFC7518AppendixCTest.groovy index b1d068c7a..4b3a995ab 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/security/RFC7518AppendixCTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/security/RFC7518AppendixCTest.groovy @@ -114,7 +114,7 @@ class RFC7518AppendixCTest { String jwe = Jwts.builder() .header().agreementPartyUInfo("Alice").agreementPartyVInfo("Bob").and() .claim("Hello", "World") - .encryptWith(bobJwk.toPublicJwk().toKey(), alg, Jwts.ENC.A128GCM) + .encryptWith(bobJwk.toPublicJwk().toKey(), alg, Jwe.alg.A128GCM) .compact() // Ensure the protected header produced by JJWT is identical to the one in the RFC: diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/security/RFC7520Section4Test.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/security/RFC7520Section4Test.groovy index befb91de5..7d828a7c3 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/security/RFC7520Section4Test.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/security/RFC7520Section4Test.groovy @@ -15,6 +15,7 @@ */ package io.jsonwebtoken.impl.security +import io.jsonwebtoken.Jws import io.jsonwebtoken.Jwts import io.jsonwebtoken.impl.io.TestSerializer import io.jsonwebtoken.io.Decoders @@ -200,7 +201,7 @@ class RFC7520Section4Test { RsaPrivateJwk jwk = Jwks.parser().build().parse(RFC7520Section3Test.FIGURE_4) as RsaPrivateJwk RSAPrivateKey key = jwk.toKey() - def alg = Jwts.SIG.RS256 + def alg = Jws.alg.RS256 // because Maps are not guaranteed to have the same order as defined in the RFC, we create an asserting // Serializer here to check the constructed data, and then, after guaranteeing the same data, return @@ -237,7 +238,7 @@ class RFC7520Section4Test { RsaPrivateJwk jwk = Jwks.parser().build().parse(RFC7520Section3Test.FIGURE_4) as RsaPrivateJwk RSAPrivateKey key = jwk.toKey() - def alg = Jwts.SIG.PS384 + def alg = Jws.alg.PS384 String kid = 'bilbo.baggins@hobbiton.example' // because Maps are not guaranteed to have the same order as defined in the RFC, we create an asserting @@ -284,7 +285,7 @@ class RFC7520Section4Test { EcPrivateJwk jwk = Jwks.parser().build().parse(RFC7520Section3Test.FIGURE_2) as EcPrivateJwk ECPrivateKey key = jwk.toKey() - def alg = Jwts.SIG.ES512 + def alg = Jws.alg.ES512 // because Maps are not guaranteed to have the same order as defined in the RFC, we create an asserting // Serializer here to check the constructed data, and then, after guaranteeing the same data, return @@ -329,7 +330,7 @@ class RFC7520Section4Test { SecretJwk jwk = Jwks.parser().build().parse(RFC7520Section3Test.FIGURE_5) as SecretJwk SecretKey key = jwk.toKey() - def alg = Jwts.SIG.HS256 + def alg = Jws.alg.HS256 // because Maps are not guaranteed to have the same order as defined in the RFC, we create an asserting // Serializer here to check the constructed data, and then, after guaranteeing the same data, return @@ -367,7 +368,7 @@ class RFC7520Section4Test { SecretJwk jwk = Jwks.parser().build().parse(RFC7520Section3Test.FIGURE_5) as SecretJwk SecretKey key = jwk.toKey() - def alg = Jwts.SIG.HS256 + def alg = Jws.alg.HS256 // because Maps are not guaranteed to have the same order as defined in the RFC, we create an asserting // Serializer here to check the constructed data, and then, after guaranteeing the same data, return diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/security/RFC8037AppendixATest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/security/RFC8037AppendixATest.groovy index cb01b4398..266496efe 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/security/RFC8037AppendixATest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/security/RFC8037AppendixATest.groovy @@ -15,6 +15,8 @@ */ package io.jsonwebtoken.impl.security +import io.jsonwebtoken.Jwe +import io.jsonwebtoken.Jws import io.jsonwebtoken.Jwts import io.jsonwebtoken.impl.RfcTests import io.jsonwebtoken.security.Curve @@ -104,7 +106,7 @@ class RFC8037AppendixATest { def privJwk = a1Jwk() String compact = Jwts.builder() .content(A4_JWS_PAYLOAD.getBytes(StandardCharsets.UTF_8)) - .signWith(privJwk.toKey() as PrivateKey, Jwts.SIG.EdDSA) + .signWith(privJwk.toKey() as PrivateKey, Jws.alg.EdDSA) .compact() assertEquals A4_JWS_COMPACT, compact @@ -153,7 +155,7 @@ class RFC8037AppendixATest { ]).build() as OctetPrivateJwk // ensure this is used during key algorithm execution per the RFC test case: - def alg = new EcdhKeyAlgorithm(Jwts.KEY.A128KW) { + def alg = new EcdhKeyAlgorithm(Jwe.enc.A128KW) { @Override protected KeyPair generateKeyPair(Curve curve, Provider provider, SecureRandom random) { return ephemJwk.toKeyPair().toJavaKeyPair() @@ -168,7 +170,7 @@ class RFC8037AppendixATest { String jwe = Jwts.builder() .header().keyId(bobPrivJwk.getId()).and() .setIssuer(issuer) - .encryptWith(bobPrivJwk.toPublicJwk().toKey() as PublicKey, alg, Jwts.ENC.A128GCM) + .encryptWith(bobPrivJwk.toPublicJwk().toKey() as PublicKey, alg, Jwe.alg.A128GCM) .compact() // the constructed JWE should have the following protected header: @@ -244,7 +246,7 @@ class RFC8037AppendixATest { ]).build() as OctetPrivateJwk // ensure this is used during key algorithm execution per the RFC test case: - def alg = new EcdhKeyAlgorithm(Jwts.KEY.A256KW) { + def alg = new EcdhKeyAlgorithm(Jwe.enc.A256KW) { @Override protected KeyPair generateKeyPair(Curve curve, Provider provider, SecureRandom random) { return ephemJwk.toKeyPair().toJavaKeyPair() @@ -259,7 +261,7 @@ class RFC8037AppendixATest { String jwe = Jwts.builder() .header().keyId(bobPrivJwk.getId()).and() //value will be "Dave" as noted above .issuer(issuer) - .encryptWith(bobPrivJwk.toPublicJwk().toKey() as PublicKey, alg, Jwts.ENC.A256GCM) + .encryptWith(bobPrivJwk.toPublicJwk().toKey() as PublicKey, alg, Jwe.alg.A256GCM) .compact() // the constructed JWE should have the following protected header: diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/security/RsaSignatureAlgorithmTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/security/RsaSignatureAlgorithmTest.groovy index 05d24d73a..375124f41 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/security/RsaSignatureAlgorithmTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/security/RsaSignatureAlgorithmTest.groovy @@ -15,7 +15,7 @@ */ package io.jsonwebtoken.impl.security -import io.jsonwebtoken.Jwts +import io.jsonwebtoken.Jws import io.jsonwebtoken.impl.io.Streams import io.jsonwebtoken.impl.lang.Bytes import io.jsonwebtoken.impl.lang.CheckedFunction @@ -35,7 +35,7 @@ import static org.junit.Assert.* class RsaSignatureAlgorithmTest { - static final Collection algs = Jwts.SIG.get().values().findAll({ + static final Collection algs = Jws.alg.registry().values().findAll({ it instanceof RsaSignatureAlgorithm }) as Collection @@ -90,7 +90,7 @@ class RsaSignatureAlgorithmTest { RSAPublicKey key = createMock(RSAPublicKey) def request = new DefaultSecureRequest(Streams.of(new byte[1]), null, null, key) try { - Jwts.SIG.RS256.digest(request) + Jws.alg.RS256.digest(request) fail() } catch (InvalidKeyException e) { String expected = "RS256 signing keys must be PrivateKeys (implement java.security.PrivateKey). " + @@ -126,7 +126,7 @@ class RsaSignatureAlgorithmTest { String msg = "The RSA signing key size (aka modulus bit length) is 1024 bits which is not secure " + "enough for the ${it.getId()} algorithm. The JWT JWA Specification (RFC 7518, Section " + "${section}) states that RSA keys " + - "MUST have a size >= 2048 bits. Consider using the Jwts.SIG.${id}.keyPair() " + + "MUST have a size >= 2048 bits. Consider using the Jws.alg.${id}.keyPair() " + "builder to create a KeyPair guaranteed to be secure enough for ${id}. See " + "https://tools.ietf.org/html/rfc7518#section-${section} for more information." assertEquals msg, expected.getMessage() diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/security/SecretJwkFactoryTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/security/SecretJwkFactoryTest.groovy index 4eeb81062..474d56ce7 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/security/SecretJwkFactoryTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/security/SecretJwkFactoryTest.groovy @@ -15,7 +15,7 @@ */ package io.jsonwebtoken.impl.security -import io.jsonwebtoken.Jwts +import io.jsonwebtoken.Jws import io.jsonwebtoken.impl.lang.Bytes import io.jsonwebtoken.io.Encoders import io.jsonwebtoken.security.* @@ -32,7 +32,7 @@ import static org.junit.Assert.* class SecretJwkFactoryTest { private static Set macAlgs() { - return Jwts.SIG.get().values().findAll({ it -> it instanceof MacAlgorithm }) as Collection + return Jws.alg.registry().values().findAll({ it -> it instanceof MacAlgorithm }) as Collection } @Test @@ -138,7 +138,7 @@ class SecretJwkFactoryTest { // 'oct' type, but 'alg' value is not a secret key algorithm (and therefore malformed) void testMismatchedAlgorithm() { try { - Jwks.builder().key(TestKeys.NA256).add('alg', Jwts.SIG.RS256.getId()).build() + Jwks.builder().key(TestKeys.NA256).add('alg', Jws.alg.RS256.getId()).build() fail() } catch (MalformedKeyException expected) { String msg = "Invalid Secret JWK ${AbstractJwk.ALG} value 'RS256'. Secret JWKs may only be used with " + diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/security/TestKeys.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/security/TestKeys.groovy index 95226c9c9..d08bc4518 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/security/TestKeys.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/security/TestKeys.groovy @@ -16,7 +16,8 @@ package io.jsonwebtoken.impl.security import io.jsonwebtoken.Identifiable -import io.jsonwebtoken.Jwts +import io.jsonwebtoken.Jwe +import io.jsonwebtoken.Jws import io.jsonwebtoken.lang.Collections import io.jsonwebtoken.security.Jwks @@ -38,9 +39,9 @@ class TestKeys { // ======================================================= // Secret Keys // ======================================================= - static SecretKey HS256 = Jwts.SIG.HS256.key().build() - static SecretKey HS384 = Jwts.SIG.HS384.key().build() - static SecretKey HS512 = Jwts.SIG.HS512.key().build() + static SecretKey HS256 = Jws.alg.HS256.key().build() + static SecretKey HS384 = Jws.alg.HS384.key().build() + static SecretKey HS512 = Jws.alg.HS512.key().build() static Collection HS = Collections.setOf(HS256, HS384, HS512) static SecretKey NA256 = new SecretKeySpec(HS256.encoded, "NONE") @@ -51,15 +52,15 @@ class TestKeys { static SecretKey A128GCM, A192GCM, A256GCM, A128KW, A192KW, A256KW, A128GCMKW, A192GCMKW, A256GCMKW static Collection AGCM static { - A128GCM = A128KW = A128GCMKW = Jwts.ENC.A128GCM.key().build() - A192GCM = A192KW = A192GCMKW = Jwts.ENC.A192GCM.key().build() - A256GCM = A256KW = A256GCMKW = Jwts.ENC.A256GCM.key().build() + A128GCM = A128KW = A128GCMKW = Jwe.alg.A128GCM.key().build() + A192GCM = A192KW = A192GCMKW = Jwe.alg.A192GCM.key().build() + A256GCM = A256KW = A256GCMKW = Jwe.alg.A256GCM.key().build() AGCM = Collections.setOf(A128GCM, A192GCM, A256GCM) } - static SecretKey A128CBC_HS256 = Jwts.ENC.A128CBC_HS256.key().build() - static SecretKey A192CBC_HS384 = Jwts.ENC.A192CBC_HS384.key().build() - static SecretKey A256CBC_HS512 = Jwts.ENC.A256CBC_HS512.key().build() + static SecretKey A128CBC_HS256 = Jwe.alg.A128CBC_HS256.key().build() + static SecretKey A192CBC_HS384 = Jwe.alg.A192CBC_HS384.key().build() + static SecretKey A256CBC_HS512 = Jwe.alg.A256CBC_HS512.key().build() static Collection ACBC = Collections.setOf(A128CBC_HS256, A192CBC_HS384, A256CBC_HS512) static Collection SECRET = new LinkedHashSet<>() @@ -73,9 +74,9 @@ class TestKeys { // ======================================================= // Elliptic Curve Keys & Certificates // ======================================================= - static Bundle ES256 = TestCertificates.readBundle(Jwts.SIG.ES256) - static Bundle ES384 = TestCertificates.readBundle(Jwts.SIG.ES384) - static Bundle ES512 = TestCertificates.readBundle(Jwts.SIG.ES512) + static Bundle ES256 = TestCertificates.readBundle(Jws.alg.ES256) + static Bundle ES384 = TestCertificates.readBundle(Jws.alg.ES384) + static Bundle ES512 = TestCertificates.readBundle(Jws.alg.ES512) static Set EC = Collections.setOf(ES256, ES384, ES512) static Bundle Ed25519 = TestCertificates.readBundle(Jwks.CRV.Ed25519) @@ -89,12 +90,12 @@ class TestKeys { // ======================================================= // RSA Keys & Certificates // ======================================================= - static Bundle RS256 = TestCertificates.readBundle(Jwts.SIG.RS256) - static Bundle RS384 = TestCertificates.readBundle(Jwts.SIG.RS384) - static Bundle RS512 = TestCertificates.readBundle(Jwts.SIG.RS512) - static Bundle PS256 = TestCertificates.readBundle(Jwts.SIG.PS256) - static Bundle PS384 = TestCertificates.readBundle(Jwts.SIG.PS384) - static Bundle PS512 = TestCertificates.readBundle(Jwts.SIG.PS512) + static Bundle RS256 = TestCertificates.readBundle(Jws.alg.RS256) + static Bundle RS384 = TestCertificates.readBundle(Jws.alg.RS384) + static Bundle RS512 = TestCertificates.readBundle(Jws.alg.RS512) + static Bundle PS256 = TestCertificates.readBundle(Jws.alg.PS256) + static Bundle PS384 = TestCertificates.readBundle(Jws.alg.PS384) + static Bundle PS512 = TestCertificates.readBundle(Jws.alg.PS512) // static Set PKCSv15 = Collections.setOf(RS256, RS384, RS512) // static Set RSASSA_PSS = Collections.setOf(PS256, PS384, PS512) static Set RSA = Collections.setOf(RS256, RS384, RS512, PS256, PS384, PS512) diff --git a/impl/src/test/groovy/io/jsonwebtoken/issues/Issue365Test.groovy b/impl/src/test/groovy/io/jsonwebtoken/issues/Issue365Test.groovy index a6bae5c96..5a1a7ff18 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/issues/Issue365Test.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/issues/Issue365Test.groovy @@ -15,9 +15,7 @@ */ package io.jsonwebtoken.issues -import io.jsonwebtoken.Header -import io.jsonwebtoken.Jwts -import io.jsonwebtoken.Locator +import io.jsonwebtoken.* import io.jsonwebtoken.impl.DefaultJwtBuilder import io.jsonwebtoken.impl.DefaultJwtParser import io.jsonwebtoken.impl.security.TestKeys @@ -39,13 +37,13 @@ class Issue365Test { private static final Collection sigalgs() { - def algs = Jwts.SIG.get().values() + def algs = Jws.alg.registry().values() .findAll({ it -> it instanceof SignatureAlgorithm }) return algs as Collection } private static final Collection> asymKeyAlgs() { - def algs = Jwts.KEY.get().values() + def algs = Jwe.enc.registry().values() .findAll({ it -> it.id.startsWith('R') || it.id.startsWith('E') }) return algs as Collection> } @@ -107,7 +105,7 @@ class Issue365Test { void testEncryptWithPrivateKey() { for (def alg : asymKeyAlgs) { try { - Jwts.builder().issuer('me').encryptWith(new TestPrivateKey(), alg, Jwts.ENC.A256GCM).compact() + Jwts.builder().issuer('me').encryptWith(new TestPrivateKey(), alg, Jwe.alg.A256GCM).compact() fail() } catch (IllegalArgumentException expected) { assertEquals DefaultJwtBuilder.PRIV_KEY_ENC_MSG, expected.getMessage() @@ -118,7 +116,7 @@ class Issue365Test { @Test void testDecryptWithPublicKey() { def pub = TestKeys.RS256.pair.public - String jwe = Jwts.builder().issuer('me').encryptWith(pub, Jwts.KEY.RSA1_5, Jwts.ENC.A256GCM).compact() + String jwe = Jwts.builder().issuer('me').encryptWith(pub, Jwe.enc.RSA1_5, Jwe.alg.A256GCM).compact() try { Jwts.parser().decryptWith(new TestPublicKey()).build().parseEncryptedClaims(jwe) fail() @@ -130,7 +128,7 @@ class Issue365Test { @Test void testDecryptWithKeyLocatorPublicKey() { def pub = TestKeys.RS256.pair.public - String jwe = Jwts.builder().issuer('me').encryptWith(pub, Jwts.KEY.RSA1_5, Jwts.ENC.A256GCM).compact() + String jwe = Jwts.builder().issuer('me').encryptWith(pub, Jwe.enc.RSA1_5, Jwe.alg.A256GCM).compact() try { Jwts.parser().keyLocator(new Locator() { @Override diff --git a/impl/src/test/groovy/io/jsonwebtoken/security/EncryptionAlgorithmsTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/security/EncryptionAlgorithmsTest.groovy index 2a0b02625..ccf5a9d4f 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/security/EncryptionAlgorithmsTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/security/EncryptionAlgorithmsTest.groovy @@ -15,7 +15,7 @@ */ package io.jsonwebtoken.security -import io.jsonwebtoken.Jwts +import io.jsonwebtoken.Jwe import io.jsonwebtoken.impl.io.Streams import io.jsonwebtoken.impl.security.DefaultAeadRequest import io.jsonwebtoken.impl.security.DefaultAeadResult @@ -26,7 +26,7 @@ import org.junit.Test import static org.junit.Assert.* /** - * Tests the {@link Jwts.ENC} implementation. + * Tests the {@link Jwe.alg} implementation. * * @since 0.12.0 */ @@ -53,7 +53,7 @@ class EncryptionAlgorithmsTest { private static final String AAD = 'You can get with this, or you can get with that' private static final byte[] AAD_BYTES = AAD.getBytes("UTF-8") - private static final Registry registry = Jwts.ENC.get() + private static final Registry registry = Jwe.alg.registry() static boolean contains(AeadAlgorithm alg) { return registry.containsValue(alg) @@ -62,12 +62,12 @@ class EncryptionAlgorithmsTest { @Test void testValues() { assertEquals 6, registry.values().size() - assertTrue(contains(Jwts.ENC.A128CBC_HS256) && - contains(Jwts.ENC.A192CBC_HS384) && - contains(Jwts.ENC.A256CBC_HS512) && - contains(Jwts.ENC.A128GCM) && - contains(Jwts.ENC.A192GCM) && - contains(Jwts.ENC.A256GCM) + assertTrue(contains(Jwe.alg.A128CBC_HS256) && + contains(Jwe.alg.A192CBC_HS384) && + contains(Jwe.alg.A256CBC_HS512) && + contains(Jwe.alg.A128GCM) && + contains(Jwe.alg.A192GCM) && + contains(Jwe.alg.A256GCM) ) } diff --git a/impl/src/test/groovy/io/jsonwebtoken/security/KeyAlgorithmsTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/security/KeyAlgorithmsTest.groovy index 9f5e7e8d9..b67f73e66 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/security/KeyAlgorithmsTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/security/KeyAlgorithmsTest.groovy @@ -15,7 +15,7 @@ */ package io.jsonwebtoken.security -import io.jsonwebtoken.Jwts +import io.jsonwebtoken.Jwe import org.junit.Test import java.security.Key @@ -23,62 +23,62 @@ import java.security.Key import static org.junit.Assert.* /** - * Tests {@link Jwts.KEY} values. + * Tests {@link Jwe.enc} values. * * @since 0.12.0 */ class KeyAlgorithmsTest { static boolean contains(KeyAlgorithm alg) { - return Jwts.KEY.get().values().contains(alg) + return Jwe.enc.registry().values().contains(alg) } @Test void testValues() { - assertEquals 17, Jwts.KEY.get().values().size() - assertTrue(contains(Jwts.KEY.DIRECT) && - contains(Jwts.KEY.A128KW) && - contains(Jwts.KEY.A192KW) && - contains(Jwts.KEY.A256KW) && - contains(Jwts.KEY.A128GCMKW) && - contains(Jwts.KEY.A192GCMKW) && - contains(Jwts.KEY.A256GCMKW) && - contains(Jwts.KEY.PBES2_HS256_A128KW) && - contains(Jwts.KEY.PBES2_HS384_A192KW) && - contains(Jwts.KEY.PBES2_HS512_A256KW) && - contains(Jwts.KEY.RSA1_5) && - contains(Jwts.KEY.RSA_OAEP) && - contains(Jwts.KEY.RSA_OAEP_256) && - contains(Jwts.KEY.ECDH_ES) && - contains(Jwts.KEY.ECDH_ES_A128KW) && - contains(Jwts.KEY.ECDH_ES_A192KW) && - contains(Jwts.KEY.ECDH_ES_A256KW) + assertEquals 17, Jwe.enc.registry().values().size() + assertTrue(contains(Jwe.enc.DIRECT) && + contains(Jwe.enc.A128KW) && + contains(Jwe.enc.A192KW) && + contains(Jwe.enc.A256KW) && + contains(Jwe.enc.A128GCMKW) && + contains(Jwe.enc.A192GCMKW) && + contains(Jwe.enc.A256GCMKW) && + contains(Jwe.enc.PBES2_HS256_A128KW) && + contains(Jwe.enc.PBES2_HS384_A192KW) && + contains(Jwe.enc.PBES2_HS512_A256KW) && + contains(Jwe.enc.RSA1_5) && + contains(Jwe.enc.RSA_OAEP) && + contains(Jwe.enc.RSA_OAEP_256) && + contains(Jwe.enc.ECDH_ES) && + contains(Jwe.enc.ECDH_ES_A128KW) && + contains(Jwe.enc.ECDH_ES_A192KW) && + contains(Jwe.enc.ECDH_ES_A256KW) ) } @Test void testForKey() { - for (KeyAlgorithm alg : Jwts.KEY.get().values()) { - assertSame alg, Jwts.KEY.get().forKey(alg.getId()) + for (KeyAlgorithm alg : Jwe.enc.registry().values()) { + assertSame alg, Jwe.enc.registry().forKey(alg.getId()) } } @Test(expected = IllegalArgumentException) void testForKeyWithInvalidId() { //unlike the 'get' paradigm, 'key' requires the value to exist - Jwts.KEY.get().forKey('invalid') + Jwe.enc.registry().forKey('invalid') } @Test void testGet() { - for (KeyAlgorithm alg : Jwts.KEY.get().values()) { - assertSame alg, Jwts.KEY.get().get(alg.getId()) + for (KeyAlgorithm alg : Jwe.enc.registry().values()) { + assertSame alg, Jwe.enc.registry().get(alg.getId()) } } @Test void testGetWithInvalidId() { // 'get' paradigm can return null if not found - assertNull Jwts.KEY.get().get('invalid') + assertNull Jwe.enc.registry().get('invalid') } } diff --git a/impl/src/test/groovy/io/jsonwebtoken/security/KeysTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/security/KeysTest.groovy index 2590eb8d9..2aaee00ac 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/security/KeysTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/security/KeysTest.groovy @@ -16,7 +16,7 @@ //file:noinspection GrDeprecatedAPIUsage package io.jsonwebtoken.security -import io.jsonwebtoken.Jwts +import io.jsonwebtoken.Jws import io.jsonwebtoken.impl.DefaultJwtBuilder import io.jsonwebtoken.impl.lang.Bytes import io.jsonwebtoken.impl.security.* @@ -73,7 +73,7 @@ class KeysTest { "is not secure enough for any JWT HMAC-SHA algorithm. The JWT " + "JWA Specification (RFC 7518, Section 3.2) states that keys used with HMAC-SHA algorithms MUST have a " + "size >= 256 bits (the key size must be greater than or equal to the hash " + - "output size). Consider using the Jwts.SIG.HS256.key() builder (or " + + "output size). Consider using the Jws.alg.HS256.key() builder (or " + "HS384.key() or HS512.key()) to create a key guaranteed to be secure enough " + "for your preferred HMAC-SHA algorithm. See " + "https://tools.ietf.org/html/rfc7518#section-3.2 for more information." as String, expected.message @@ -129,7 +129,7 @@ class KeysTest { @Test void testSecretKeyFor() { - for (SecureDigestAlgorithm alg : Jwts.SIG.get().values()) { + for (SecureDigestAlgorithm alg : Jws.alg.registry().values()) { if (alg instanceof MacAlgorithm) { SecretKey key = alg.key().build() assertEquals alg.getKeyBitLength(), Bytes.bitLength(key.getEncoded()) @@ -208,7 +208,7 @@ class KeysTest { @Test void testKeyPairBuilder() { - Collection algs = Jwts.SIG.get().values() + Collection algs = Jws.alg.registry().values() .findAll({ it instanceof KeyPairBuilderSupplier }) as Collection for (SignatureAlgorithm alg : algs) { diff --git a/impl/src/test/groovy/io/jsonwebtoken/security/StandardAlgorithmsTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/security/StandardAlgorithmsTest.groovy index 4d7563cf2..241e2a75f 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/security/StandardAlgorithmsTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/security/StandardAlgorithmsTest.groovy @@ -15,6 +15,8 @@ */ package io.jsonwebtoken.security +import io.jsonwebtoken.Jwe +import io.jsonwebtoken.Jws import io.jsonwebtoken.Jwts import io.jsonwebtoken.lang.Registry import org.junit.Test @@ -23,7 +25,7 @@ import static org.junit.Assert.* class StandardAlgorithmsTest { - static final List> registries = [Jwts.SIG.get(), Jwts.ENC.get(), Jwts.KEY.get(), Jwts.ZIP.get(), Jwks.HASH.get()] + static final List> registries = [Jws.alg.registry(), Jwe.alg.registry(), Jwe.enc.registry(), Jwts.ZIP.get(), Jwks.HASH.get()] private static void eachRegAlg(Closure c) { registries.each { reg -> reg.values().each { c(reg, it) } } @@ -31,9 +33,9 @@ class StandardAlgorithmsTest { @Test void testSize() { - assertEquals 14, Jwts.SIG.get().size() - assertEquals 6, Jwts.ENC.get().size() - assertEquals 17, Jwts.KEY.get().size() + assertEquals 14, Jws.alg.registry().size() + assertEquals 6, Jwe.alg.registry().size() + assertEquals 17, Jwe.enc.registry().size() assertEquals 2, Jwts.ZIP.get().size() assertEquals 6, Jwks.HASH.get().size() } diff --git a/tdjar/src/test/java/io/jsonwebtoken/all/JavaReadmeTest.java b/tdjar/src/test/java/io/jsonwebtoken/all/JavaReadmeTest.java index 652753b70..5e0d6a3bf 100644 --- a/tdjar/src/test/java/io/jsonwebtoken/all/JavaReadmeTest.java +++ b/tdjar/src/test/java/io/jsonwebtoken/all/JavaReadmeTest.java @@ -16,6 +16,7 @@ package io.jsonwebtoken.all; import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwe; import io.jsonwebtoken.Jws; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.security.AeadAlgorithm; @@ -64,7 +65,7 @@ public class JavaReadmeTest { @Test public void testExampleDetachedUnencodedPayload() { // create a test key for this example: - SecretKey testKey = Jwts.SIG.HS512.key().build(); + SecretKey testKey = Jws.alg.HS512.key().build(); String message = "Hello World. It's a Beautiful Day!"; byte[] content = message.getBytes(StandardCharsets.UTF_8); @@ -87,7 +88,7 @@ public void testExampleDetachedUnencodedPayload() { @Test public void testExampleNonDetachedUnencodedPayload() { // create a test key for this example: - SecretKey testKey = Jwts.SIG.HS512.key().build(); + SecretKey testKey = Jws.alg.HS512.key().build(); String claimsString = "{\"sub\":\"joe\",\"iss\":\"me\"}"; @@ -118,7 +119,7 @@ public void testExampleNonDetachedUnencodedPayload() { @Test public void testExampleJwsHS() { // Create a test key suitable for the desired HMAC-SHA algorithm: - MacAlgorithm alg = Jwts.SIG.HS512; //or HS384 or HS256 + MacAlgorithm alg = Jws.alg.HS512; //or HS384 or HS256 SecretKey key = alg.key().build(); String message = "Hello World!"; @@ -139,7 +140,7 @@ public void testExampleJwsHS() { @Test public void testExampleJwsRSA() { // Create a test key suitable for the desired RSA signature algorithm: - SignatureAlgorithm alg = Jwts.SIG.RS512; //or PS512, RS256, etc... + SignatureAlgorithm alg = Jws.alg.RS512; //or PS512, RS256, etc... KeyPair pair = alg.keyPair().build(); // Bob creates the compact JWS with his RSA private key: @@ -161,7 +162,7 @@ public void testExampleJwsRSA() { @Test public void testExampleJwsECDSA() { // Create a test key suitable for the desired ECDSA signature algorithm: - SignatureAlgorithm alg = Jwts.SIG.ES512; //or ES256 or ES384 + SignatureAlgorithm alg = Jws.alg.ES512; //or ES256 or ES384 KeyPair pair = alg.keyPair().build(); // Bob creates the compact JWS with his EC private key: @@ -188,7 +189,7 @@ public void testExampleJwsEdDSA() { // Bob creates the compact JWS with his Edwards Curve private key: String jws = Jwts.builder().subject("Alice") - .signWith(pair.getPrivate(), Jwts.SIG.EdDSA) // <-- Bob's Edwards Curve private key w/ EdDSA + .signWith(pair.getPrivate(), Jws.alg.EdDSA) // <-- Bob's Edwards Curve private key w/ EdDSA .compact(); // Alice receives and verifies the compact JWS came from Bob: @@ -206,7 +207,7 @@ public void testExampleJwsEdDSA() { public void testExampleJweDir() { // Create a test key suitable for the desired payload encryption algorithm: // (A*GCM algorithms are recommended, but require JDK 8 or later) - AeadAlgorithm enc = Jwts.ENC.A256GCM; //or A128GCM, A192GCM, A256CBC-HS512, etc... + AeadAlgorithm enc = Jwe.alg.A256GCM; //or A128GCM, A192GCM, A256CBC-HS512, etc... SecretKey key = enc.key().build(); String message = "Live long and prosper."; @@ -227,12 +228,12 @@ public void testExampleJweDir() { @Test public void testExampleJweRSA() { // Create a test KeyPair suitable for the desired RSA key algorithm: - KeyPair pair = Jwts.SIG.RS512.keyPair().build(); + KeyPair pair = Jws.alg.RS512.keyPair().build(); // Choose the key algorithm used encrypt the payload key: - KeyAlgorithm alg = Jwts.KEY.RSA_OAEP_256; //or RSA_OAEP or RSA1_5 + KeyAlgorithm alg = Jwe.enc.RSA_OAEP_256; //or RSA_OAEP or RSA1_5 // Choose the Encryption Algorithm to encrypt the payload: - AeadAlgorithm enc = Jwts.ENC.A256GCM; //or A192GCM, A128GCM, A256CBC-HS512, etc... + AeadAlgorithm enc = Jwe.alg.A256GCM; //or A192GCM, A128GCM, A256CBC-HS512, etc... // Bob creates the compact JWE with Alice's RSA public key so only she may read it: String jwe = Jwts.builder().audience().add("Alice").and() @@ -253,11 +254,11 @@ public void testExampleJweRSA() { @Test public void testExampleJweAESKW() { // Create a test SecretKey suitable for the desired AES Key Wrap algorithm: - SecretKeyAlgorithm alg = Jwts.KEY.A256GCMKW; //or A192GCMKW, A128GCMKW, A256KW, etc... + SecretKeyAlgorithm alg = Jwe.enc.A256GCMKW; //or A192GCMKW, A128GCMKW, A256KW, etc... SecretKey key = alg.key().build(); // Chooose the Encryption Algorithm used to encrypt the payload: - AeadAlgorithm enc = Jwts.ENC.A256GCM; //or A192GCM, A128GCM, A256CBC-HS512, etc... + AeadAlgorithm enc = Jwe.alg.A256GCM; //or A192GCM, A128GCM, A256CBC-HS512, etc... // Create the compact JWE: String jwe = Jwts.builder().issuer("me").encryptWith(key, alg, enc).compact(); @@ -275,12 +276,12 @@ public void testExampleJweAESKW() { @Test public void testExampleJweECDHES() { // Create a test KeyPair suitable for the desired EC key algorithm: - KeyPair pair = Jwts.SIG.ES512.keyPair().build(); + KeyPair pair = Jws.alg.ES512.keyPair().build(); // Choose the key algorithm used encrypt the payload key: - KeyAlgorithm alg = Jwts.KEY.ECDH_ES_A256KW; //ECDH_ES_A192KW, etc... + KeyAlgorithm alg = Jwe.enc.ECDH_ES_A256KW; //ECDH_ES_A192KW, etc... // Choose the Encryption Algorithm to encrypt the payload: - AeadAlgorithm enc = Jwts.ENC.A256GCM; //or A192GCM, A128GCM, A256CBC-HS512, etc... + AeadAlgorithm enc = Jwe.alg.A256GCM; //or A192GCM, A128GCM, A256CBC-HS512, etc... // Bob creates the compact JWE with Alice's EC public key so only she may read it: String jwe = Jwts.builder().audience().add("Alice").and() @@ -305,7 +306,7 @@ public void testExampleJwePassword() { Password password = Keys.password(pw.toCharArray()); // Choose the desired PBES2 key derivation algorithm: - KeyAlgorithm alg = Jwts.KEY.PBES2_HS512_A256KW; //or PBES2_HS384... + KeyAlgorithm alg = Jwe.enc.PBES2_HS512_A256KW; //or PBES2_HS384... // Optionally choose the number of PBES2 computational iterations to use to derive the key. // This is optional - if you do not specify a value, JJWT will automatically choose a value @@ -316,7 +317,7 @@ public void testExampleJwePassword() { //int pbkdf2Iterations = 120000; //for HS512. Needs to be much higher for smaller hash algs. // Choose the Encryption Algorithm used to encrypt the payload: - AeadAlgorithm enc = Jwts.ENC.A256GCM; //or A192GCM, A128GCM, A256CBC-HS512, etc... + AeadAlgorithm enc = Jwe.alg.A256GCM; //or A192GCM, A128GCM, A256CBC-HS512, etc... // Create the compact JWE: String jwe = Jwts.builder().issuer("me") @@ -334,7 +335,7 @@ public void testExampleJwePassword() { @Test public void testExampleSecretJwk() { - SecretKey key = Jwts.SIG.HS512.key().build(); // or HS384 or HS256 + SecretKey key = Jws.alg.HS512.key().build(); // or HS384 or HS256 SecretJwk jwk = builder().key(key).idFromThumbprint().build(); assert jwk.getId().equals(jwk.thumbprint().toString()); @@ -349,7 +350,7 @@ public void testExampleSecretJwk() { @Test public void testExampleRsaPublicJwk() { - RSAPublicKey key = (RSAPublicKey) Jwts.SIG.RS512.keyPair().build().getPublic(); + RSAPublicKey key = (RSAPublicKey) Jws.alg.RS512.keyPair().build().getPublic(); RsaPublicJwk jwk = builder().key(key).idFromThumbprint().build(); assert jwk.getId().equals(jwk.thumbprint().toString()); @@ -364,7 +365,7 @@ public void testExampleRsaPublicJwk() { @Test public void testExampleRsaPrivateJwk() { - KeyPair pair = Jwts.SIG.RS512.keyPair().build(); + KeyPair pair = Jws.alg.RS512.keyPair().build(); RSAPublicKey pubKey = (RSAPublicKey) pair.getPublic(); RSAPrivateKey privKey = (RSAPrivateKey) pair.getPrivate(); @@ -385,7 +386,7 @@ public void testExampleRsaPrivateJwk() { @Test public void testExampleEcPublicJwk() { - ECPublicKey key = (ECPublicKey) Jwts.SIG.ES512.keyPair().build().getPublic(); + ECPublicKey key = (ECPublicKey) Jws.alg.ES512.keyPair().build().getPublic(); EcPublicJwk jwk = builder().key(key).idFromThumbprint().build(); assert jwk.getId().equals(jwk.thumbprint().toString()); @@ -400,7 +401,7 @@ public void testExampleEcPublicJwk() { @Test public void testExampleEcPrivateJwk() { - KeyPair pair = Jwts.SIG.ES512.keyPair().build(); + KeyPair pair = Jws.alg.ES512.keyPair().build(); ECPublicKey pubKey = (ECPublicKey) pair.getPublic(); ECPrivateKey privKey = (ECPrivateKey) pair.getPrivate();