test cleanup, renamed SymmetricAeadAlgorithm to AeadAlgorithm (symmetric is always required in the JWT RFCs, no need for the extra verbosity)

This commit is contained in:
Les Hazlewood 2021-10-12 18:07:47 -07:00
parent e6db3da6b0
commit f77697cef1
48 changed files with 262 additions and 379 deletions

View File

@ -15,8 +15,8 @@
*/
package io.jsonwebtoken;
import io.jsonwebtoken.security.AeadAlgorithm;
import io.jsonwebtoken.security.KeyAlgorithm;
import io.jsonwebtoken.security.SymmetricAeadAlgorithm;
import javax.crypto.SecretKey;
import java.security.Key;
@ -26,7 +26,7 @@ import java.security.Key;
*/
public interface JweBuilder extends JwtBuilder<JweBuilder> {
JweBuilder encryptWith(SymmetricAeadAlgorithm enc);
JweBuilder encryptWith(AeadAlgorithm enc);
JweBuilder withKey(SecretKey key);

View File

@ -17,9 +17,9 @@ package io.jsonwebtoken;
import io.jsonwebtoken.io.Decoder;
import io.jsonwebtoken.io.Deserializer;
import io.jsonwebtoken.security.AeadAlgorithm;
import io.jsonwebtoken.security.KeyAlgorithm;
import io.jsonwebtoken.security.SignatureAlgorithm;
import io.jsonwebtoken.security.SymmetricAeadAlgorithm;
import java.security.Key;
import java.security.Provider;
@ -339,7 +339,7 @@ public interface JwtParserBuilder {
@Deprecated
JwtParserBuilder setSigningKeyResolver(SigningKeyResolver signingKeyResolver);
JwtParserBuilder addEncryptionAlgorithms(Collection<SymmetricAeadAlgorithm> encAlgs);
JwtParserBuilder addEncryptionAlgorithms(Collection<AeadAlgorithm> encAlgs);
JwtParserBuilder addSignatureAlgorithms(Collection<SignatureAlgorithm<?,?>> sigAlgs);

View File

@ -20,9 +20,9 @@ import io.jsonwebtoken.Identifiable;
/**
* @since JJWT_RELEASE_VERSION
*/
public interface SymmetricAeadAlgorithm extends Identifiable, SecretKeyGenerator {
public interface AeadAlgorithm extends Identifiable, SecretKeyGenerator {
AeadResult encrypt(SymmetricAeadRequest request) throws SecurityException;
AeadResult encrypt(AeadRequest request) throws SecurityException;
PayloadSupplier<byte[]> decrypt(DecryptSymmetricAeadRequest request) throws SecurityException;
PayloadSupplier<byte[]> decrypt(DecryptAeadRequest request) throws SecurityException;
}

View File

@ -20,5 +20,5 @@ import javax.crypto.SecretKey;
/**
* @since JJWT_RELEASE_VERSION
*/
public interface SymmetricAeadRequest extends CryptoRequest<byte[], SecretKey>, AssociatedDataSupplier {
public interface AeadRequest extends CryptoRequest<byte[], SecretKey>, AssociatedDataSupplier {
}

View File

@ -18,5 +18,5 @@ package io.jsonwebtoken.security;
/**
* @since JJWT_RELEASE_VERSION
*/
public interface DecryptSymmetricAeadRequest extends SymmetricAeadRequest, InitializationVectorSupplier, DigestSupplier {
public interface DecryptAeadRequest extends AeadRequest, InitializationVectorSupplier, DigestSupplier {
}

View File

@ -32,7 +32,7 @@ public final class EncryptionAlgorithms {
private static final String BRIDGE_CLASSNAME = "io.jsonwebtoken.impl.security.EncryptionAlgorithmsBridge";
private static final Class<?>[] ID_ARG_TYPES = new Class[]{String.class};
public static Collection<SymmetricAeadAlgorithm> values() {
public static Collection<AeadAlgorithm> values() {
return Classes.invokeStatic(BRIDGE_CLASSNAME, "values", null, (Object[]) null);
}
@ -45,12 +45,12 @@ public final class EncryptionAlgorithms {
* @return the associated Encryption Algorithm instance or {@code null} otherwise.
* @see <a href="https://datatracker.ietf.org/doc/html/rfc7518#section-5.1">RFC 7518, Section 5.1</a>
*/
public static SymmetricAeadAlgorithm findById(String id) {
public static AeadAlgorithm findById(String id) {
Assert.hasText(id, "id cannot be null or empty.");
return Classes.invokeStatic(BRIDGE_CLASSNAME, "findById", ID_ARG_TYPES, id);
}
private static SymmetricAeadAlgorithm forId(String id) {
private static AeadAlgorithm forId(String id) {
Assert.hasText(id, "id cannot be null or empty.");
return Classes.invokeStatic(BRIDGE_CLASSNAME, "forId", ID_ARG_TYPES, id);
}
@ -60,40 +60,40 @@ public final class EncryptionAlgorithms {
* <a href="https://tools.ietf.org/html/rfc7518#section-5.2.3">RFC 7518, Section 5.2.3</a>. This algorithm
* requires a 256 bit (32 byte) key.
*/
public static final SymmetricAeadAlgorithm A128CBC_HS256 = forId("A128CBC-HS256");
public static final AeadAlgorithm A128CBC_HS256 = forId("A128CBC-HS256");
/**
* AES_192_CBC_HMAC_SHA_384 authenticated encryption algorithm, as defined by
* <a href="https://tools.ietf.org/html/rfc7518#section-5.2.4">RFC 7518, Section 5.2.4</a>. This algorithm
* requires a 384 bit (48 byte) key.
*/
public static final SymmetricAeadAlgorithm A192CBC_HS384 = forId("A192CBC-HS384");
public static final AeadAlgorithm A192CBC_HS384 = forId("A192CBC-HS384");
/**
* AES_256_CBC_HMAC_SHA_512 authenticated encryption algorithm, as defined by
* <a href="https://tools.ietf.org/html/rfc7518#section-5.2.5">RFC 7518, Section 5.2.5</a>. This algorithm
* requires a 512 bit (64 byte) key.
*/
public static final SymmetricAeadAlgorithm A256CBC_HS512 = forId("A256CBC-HS512");
public static final AeadAlgorithm A256CBC_HS512 = forId("A256CBC-HS512");
/**
* &quot;AES GCM using 128-bit key&quot; as defined by
* <a href="https://tools.ietf.org/html/rfc7518#section-5.3">RFC 7518, Section 5.3</a>. This algorithm requires
* a 128 bit (16 byte) key.
*/
public static final SymmetricAeadAlgorithm A128GCM = forId("A128GCM");
public static final AeadAlgorithm A128GCM = forId("A128GCM");
/**
* &quot;AES GCM using 192-bit key&quot; as defined by
* <a href="https://tools.ietf.org/html/rfc7518#section-5.3">RFC 7518, Section 5.3</a>. This algorithm requires
* a 192 bit (24 byte) key.
*/
public static final SymmetricAeadAlgorithm A192GCM = forId("A192GCM");
public static final AeadAlgorithm A192GCM = forId("A192GCM");
/**
* &quot;AES GCM using 256-bit key&quot; as defined by
* <a href="https://tools.ietf.org/html/rfc7518#section-5.3">RFC 7518, Section 5.3</a>. This algorithm requires
* a 256 bit (32 byte) key.
*/
public static final SymmetricAeadAlgorithm A256GCM = forId("A256GCM");
public static final AeadAlgorithm A256GCM = forId("A256GCM");
}

View File

@ -24,6 +24,7 @@ import java.util.Collection;
/**
* @since JJWT_RELEASE_VERSION
*/
@SuppressWarnings("rawtypes")
public final class KeyAlgorithms {
//prevent instantiation
@ -69,15 +70,12 @@ public final class KeyAlgorithms {
public static final KeyAlgorithm<SecretKey, SecretKey> A128GCMKW = forId0("A128GCMKW");
public static final KeyAlgorithm<SecretKey, SecretKey> A192GCMKW = forId0("A192GCMKW");
public static final KeyAlgorithm<SecretKey, SecretKey> A256GCMKW = forId0("A256GCMKW");
@SuppressWarnings("rawtypes")
public static final RsaKeyAlgorithm RSA1_5 = forId0("RSA1_5");
@SuppressWarnings("rawtypes")
public static final RsaKeyAlgorithm RSA_OAEP = forId0("RSA-OAEP");
@SuppressWarnings("rawtypes")
public static final RsaKeyAlgorithm RSA_OAEP_256 = forId0("RSA-OAEP-256");
public static final KeyAlgorithm<PbeKey, SecretKey> PBES2_HS256_A128KW = forId0("PBES2-HS256+A128KW");
public static final KeyAlgorithm<PbeKey, SecretKey> PBES2_HS384_A192KW = forId0("PBES2-HS384+A192KW");
public static final KeyAlgorithm<PbeKey, SecretKey> PBES2_HS512_A256KW = forId0("PBES2-HS512+A256KW");
public static final RsaKeyAlgorithm RSA1_5 = forId0("RSA1_5");
public static final RsaKeyAlgorithm RSA_OAEP = forId0("RSA-OAEP");
public static final RsaKeyAlgorithm RSA_OAEP_256 = forId0("RSA-OAEP-256");
public static int estimateIterations(KeyAlgorithm<PbeKey, SecretKey> alg, long desiredMillis) {
return Classes.invokeStatic(BRIDGE_CLASSNAME, "estimateIterations", ESTIMATE_ITERATIONS_ARG_TYPES, alg, desiredMillis);

View File

@ -24,7 +24,7 @@ import java.security.Key;
*/
public interface KeyRequest<K extends Key> extends SecurityRequest, KeySupplier<K> {
SymmetricAeadAlgorithm getEncryptionAlgorithm();
AeadAlgorithm getEncryptionAlgorithm();
JweHeader getHeader();
}

View File

@ -31,6 +31,8 @@ import java.security.KeyPair;
public final class Keys {
private static final String BRIDGE_CLASSNAME = "io.jsonwebtoken.impl.security.KeysBridge";
@SuppressWarnings("rawtypes")
private static final Class[] TO_PBE_ARG_TYPES = new Class[]{PBEKey.class};
//prevent instantiation
private Keys() {
@ -223,10 +225,23 @@ public final class Keys {
return asalg.generateKeyPair();
}
/**
* Returns a JJWT {@link PbeKey} directly backed by the specified JCA {@link PBEKey}. The returned instance
* is directly linked to the specified {@code PBEKey} - a call to either key's {@link SecretKey#destroy() destroy}
* method will destroy the other to ensure correct/safe cleanup for both.
*
* @param key the {@code PBEKey} to represent as a {@code PbeKey} instance.
* @return a JJWT {@link PbeKey} instance that wraps the specified JCA {@link PBEKey}
* @since JJWT_RELEASE_VERSION
*/
public static PbeKey toPbeKey(PBEKey key) {
return forPbe().forKey(key).build();
return Classes.invokeStatic(BRIDGE_CLASSNAME, "toPbeKey", TO_PBE_ARG_TYPES, new Object[]{key});
}
/**
* Returns a new {@link PbeKeyBuilder} to use to construct a {@link PbeKey} instance.
* @return
*/
public static PbeKeyBuilder<PbeKey> forPbe() {
return Classes.invokeStatic(BRIDGE_CLASSNAME, "forPbe", null, (Object[]) null);
}

View File

@ -22,8 +22,20 @@ import javax.crypto.SecretKey;
*/
public interface PbeKey extends SecretKey {
/**
* Returns a clone of the underlying password character array represented by this Key. Like all
* {@code SecretKey} implementations, if you wish to clear the backing password character array for
* safety/security reasons, call the {@link #destroy()} method, ensuring the key instance can no longer
* be used.
*
* @return a clone of the underlying password character array represented by this Key.
*/
char[] getPassword();
int getWorkFactor();
/**
* Returns the number of hashing iterations to perform.
*
* @return the number of hashing iterations to perform.
*/
int getIterations();
}

View File

@ -15,20 +15,38 @@
*/
package io.jsonwebtoken.security;
import javax.crypto.interfaces.PBEKey;
/**
* @since JJWT_RELEASE_VERSION
*/
public interface PbeKeyBuilder<K extends PbeKey> {
PbeKeyBuilder<K> forKey(PBEKey jcaKey);
PbeKeyBuilder<K> setPassword(String password);
/**
* Sets the password character array for the constructed key. This does not clone the argument - changes made
* to the backing array will be reflected by the constructed key and any {@link PbeKey#destroy()} call will do
* the same. This is to ensure that any clearing of the password argument for security/safety reasons also
* guarantees the resulting key is also cleared and vice versa.
*
* @param password password character array for the constructed key
* @return this builder for method chaining
*/
PbeKeyBuilder<K> setPassword(char[] password);
PbeKeyBuilder<K> setWorkFactor(int workFactor);
/**
* Sets the number of hashing iterations to perform when deriving an encryption key.
*
* @param iterations the number of hashing iterations to perform when deriving an encryption key.
* @return @return this builder for method chaining
*/
PbeKeyBuilder<K> setIterations(int iterations);
/**
* Constructs a new {@link PbeKey} that shares the {@link #setPassword(char[]) specified} password character array.
* Changes to that char array will be reflected in the returned key, and similarly,
* any call to the key's {@link PbeKey#destroy() destroy} method will clear/overwrite the shared char array.
* This is to ensure that any clearing of the password char array for security/safety reasons also
* guarantees the key is also cleared and vice versa.
*
* @return a new {@link PbeKey} that shares the {@link #setPassword(char[]) specified} password character array.
*/
K build();
}

View File

@ -6,14 +6,16 @@ import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.impl.lang.Function;
import io.jsonwebtoken.impl.lang.PropagatingExceptionFunction;
import io.jsonwebtoken.impl.lang.Services;
import io.jsonwebtoken.impl.security.DefaultAeadRequest;
import io.jsonwebtoken.impl.security.DefaultKeyRequest;
import io.jsonwebtoken.impl.security.DefaultSymmetricAeadRequest;
import io.jsonwebtoken.io.SerializationException;
import io.jsonwebtoken.io.Serializer;
import io.jsonwebtoken.lang.Arrays;
import io.jsonwebtoken.lang.Assert;
import io.jsonwebtoken.lang.Collections;
import io.jsonwebtoken.lang.Strings;
import io.jsonwebtoken.security.AeadAlgorithm;
import io.jsonwebtoken.security.AeadRequest;
import io.jsonwebtoken.security.AeadResult;
import io.jsonwebtoken.security.KeyAlgorithm;
import io.jsonwebtoken.security.KeyAlgorithms;
@ -22,8 +24,6 @@ import io.jsonwebtoken.security.KeyResult;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.PbeKey;
import io.jsonwebtoken.security.SecurityException;
import io.jsonwebtoken.security.SymmetricAeadAlgorithm;
import io.jsonwebtoken.security.SymmetricAeadRequest;
import javax.crypto.SecretKey;
import javax.crypto.interfaces.PBEKey;
@ -33,8 +33,8 @@ import java.util.Map;
public class DefaultJweBuilder extends DefaultJwtBuilder<JweBuilder> implements JweBuilder {
private SymmetricAeadAlgorithm enc; // MUST be Symmetric AEAD per https://tools.ietf.org/html/rfc7516#section-4.1.2
private Function<SymmetricAeadRequest, AeadResult> encFunction;
private AeadAlgorithm enc; // MUST be Symmetric AEAD per https://tools.ietf.org/html/rfc7516#section-4.1.2
private Function<AeadRequest, AeadResult> encFunction;
private KeyAlgorithm<Key, ?> alg;
private Function<KeyRequest<Key>, KeyResult> algFunction;
@ -65,13 +65,13 @@ public class DefaultJweBuilder extends DefaultJwtBuilder<JweBuilder> implements
}
@Override
public JweBuilder encryptWith(final SymmetricAeadAlgorithm enc) {
public JweBuilder encryptWith(final AeadAlgorithm enc) {
this.enc = Assert.notNull(enc, "Encryption algorithm cannot be null.");
Assert.hasText(enc.getId(), "Encryption algorithm id cannot be null or empty.");
String encMsg = enc.getId() + " encryption failed.";
this.encFunction = wrap(encMsg, new Function<SymmetricAeadRequest, AeadResult>() {
this.encFunction = wrap(encMsg, new Function<AeadRequest, AeadResult>() {
@Override
public AeadResult apply(SymmetricAeadRequest request) {
public AeadResult apply(AeadRequest request) {
return enc.encrypt(request);
}
});
@ -159,7 +159,7 @@ public class DefaultJweBuilder extends DefaultJwtBuilder<JweBuilder> implements
final String base64UrlEncodedHeader = base64UrlEncoder.encode(headerBytes);
byte[] aad = base64UrlEncodedHeader.getBytes(StandardCharsets.US_ASCII);
SymmetricAeadRequest encRequest = new DefaultSymmetricAeadRequest(provider, secureRandom, plaintext, cek, aad);
AeadRequest encRequest = new DefaultAeadRequest(provider, secureRandom, plaintext, cek, aad);
AeadResult encResult = encFunction.apply(encRequest);
byte[] iv = Assert.notEmpty(encResult.getInitializationVector(), "Encryption result must have a non-empty initialization vector.");

View File

@ -61,7 +61,8 @@ import io.jsonwebtoken.lang.Assert;
import io.jsonwebtoken.lang.Collections;
import io.jsonwebtoken.lang.DateFormats;
import io.jsonwebtoken.lang.Strings;
import io.jsonwebtoken.security.DecryptSymmetricAeadRequest;
import io.jsonwebtoken.security.AeadAlgorithm;
import io.jsonwebtoken.security.DecryptAeadRequest;
import io.jsonwebtoken.security.DecryptionKeyRequest;
import io.jsonwebtoken.security.InvalidKeyException;
import io.jsonwebtoken.security.KeyAlgorithm;
@ -70,7 +71,6 @@ import io.jsonwebtoken.security.PayloadSupplier;
import io.jsonwebtoken.security.SignatureAlgorithm;
import io.jsonwebtoken.security.SignatureAlgorithms;
import io.jsonwebtoken.security.SignatureException;
import io.jsonwebtoken.security.SymmetricAeadAlgorithm;
import io.jsonwebtoken.security.VerifySignatureRequest;
import io.jsonwebtoken.security.WeakKeyException;
@ -121,7 +121,7 @@ public class DefaultJwtParser implements JwtParser {
return locFn(JwsHeader.ALGORITHM, MISSING_JWS_ALG_MSG, SignatureAlgorithmsBridge.REGISTRY, extras);
}
private static Function<JweHeader, SymmetricAeadAlgorithm> encFn(Collection<SymmetricAeadAlgorithm> extras) {
private static Function<JweHeader, AeadAlgorithm> encFn(Collection<AeadAlgorithm> extras) {
return locFn(JweHeader.ENCRYPTION_ALGORITHM, MISSING_ENC_MSG, EncryptionAlgorithmsBridge.REGISTRY, extras);
}
@ -140,7 +140,7 @@ public class DefaultJwtParser implements JwtParser {
private final Function<JwsHeader, SignatureAlgorithm<?, ?>> signatureAlgorithmLocator;
private final Function<JweHeader, SymmetricAeadAlgorithm> encryptionAlgorithmLocator;
private final Function<JweHeader, AeadAlgorithm> encryptionAlgorithmLocator;
private final Function<JweHeader, KeyAlgorithm<?, ?>> keyAlgorithmLocator;
@ -169,7 +169,7 @@ public class DefaultJwtParser implements JwtParser {
this.signingKeyResolver = constantKeyLocator;
this.signatureAlgorithmLocator = sigFn(Collections.<SignatureAlgorithm<?, ?>>emptyList());
this.keyAlgorithmLocator = keyFn(Collections.<KeyAlgorithm<?, ?>>emptyList());
this.encryptionAlgorithmLocator = encFn(Collections.<SymmetricAeadAlgorithm>emptyList());
this.encryptionAlgorithmLocator = encFn(Collections.<AeadAlgorithm>emptyList());
this.compressionCodecLocator = new CompressionCodecLocator<>(new DefaultCompressionCodecResolver());
}
@ -186,7 +186,7 @@ public class DefaultJwtParser implements JwtParser {
CompressionCodecResolver compressionCodecResolver,
Collection<SignatureAlgorithm<?, ?>> extraSigAlgs,
Collection<KeyAlgorithm<?, ?>> extraKeyAlgs,
Collection<SymmetricAeadAlgorithm> extraEncAlgs) {
Collection<AeadAlgorithm> extraEncAlgs) {
this.provider = provider;
this.signingKeyResolver = Assert.notNull(signingKeyResolver, "SigningKeyResolver cannot be null.");
this.keyLocator = Assert.notNull(keyLocator, "Key Locator cannot be null.");
@ -438,7 +438,7 @@ public class DefaultJwtParser implements JwtParser {
if (!Strings.hasText(enc)) {
throw new MalformedJwtException(MISSING_ENC_MSG);
}
final SymmetricAeadAlgorithm encAlg = this.encryptionAlgorithmLocator.apply(jweHeader);
final AeadAlgorithm encAlg = this.encryptionAlgorithmLocator.apply(jweHeader);
if (encAlg == null) {
String msg = "Unrecognized JWE encryption algorithm '" + enc + "'.";
throw new UnsupportedJwtException(msg);
@ -466,7 +466,7 @@ public class DefaultJwtParser implements JwtParser {
throw new IllegalStateException(msg);
}
DecryptSymmetricAeadRequest decryptRequest =
DecryptAeadRequest decryptRequest =
new DefaultAeadResult(this.provider, null, bytes, cek, aad, tag, iv);
PayloadSupplier<byte[]> result = encAlg.decrypt(decryptRequest);
bytes = result.getPayload();

View File

@ -35,10 +35,10 @@ import io.jsonwebtoken.io.Decoder;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.io.Deserializer;
import io.jsonwebtoken.lang.Assert;
import io.jsonwebtoken.security.AeadAlgorithm;
import io.jsonwebtoken.security.KeyAlgorithm;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.SignatureAlgorithm;
import io.jsonwebtoken.security.SymmetricAeadAlgorithm;
import java.security.Key;
import java.security.Provider;
@ -73,7 +73,7 @@ public class DefaultJwtParserBuilder implements JwtParserBuilder {
private CompressionCodecResolver compressionCodecResolver = new DefaultCompressionCodecResolver();
private final Collection<SymmetricAeadAlgorithm> extraEncryptionAlgorithms = new LinkedHashSet<>();
private final Collection<AeadAlgorithm> extraEncryptionAlgorithms = new LinkedHashSet<>();
private final Collection<KeyAlgorithm<?, ?>> extraKeyAlgorithms = new LinkedHashSet<>();
@ -215,8 +215,8 @@ public class DefaultJwtParserBuilder implements JwtParserBuilder {
}
@Override
public JwtParserBuilder addEncryptionAlgorithms(Collection<SymmetricAeadAlgorithm> encAlgs) {
Assert.notEmpty(encAlgs, "Additional SymmetricAeadAlgorithm collection cannot be null or empty.");
public JwtParserBuilder addEncryptionAlgorithms(Collection<AeadAlgorithm> encAlgs) {
Assert.notEmpty(encAlgs, "Additional AeadAlgorithm collection cannot be null or empty.");
this.extraEncryptionAlgorithms.addAll(encAlgs);
return this;
}

View File

@ -69,13 +69,13 @@ public final class Bytes {
public static byte[] concat(byte[]... arrays) {
int len = 0;
int count = Arrays.length(arrays);
for(int i = 0; i < count; i++) {
for (int i = 0; i < count; i++) {
len += arrays[i].length;
}
byte[] output = new byte[len];
int position = 0;
if (len > 0) {
for(byte[] array : arrays) {
for (byte[] array : arrays) {
int alen = Arrays.length(array);
if (alen > 0) {
System.arraycopy(array, 0, output, position, alen);
@ -87,7 +87,7 @@ public final class Bytes {
}
public static long bitLength(byte[] bytes) {
return bytes == null ? 0 : bytes.length * (long)Byte.SIZE;
return bytes == null ? 0 : bytes.length * (long) Byte.SIZE;
}
public static String bitsMsg(long bitLength) {
@ -95,7 +95,7 @@ public final class Bytes {
}
public static String bytesMsg(int byteArrayLength) {
return bitsMsg((long)byteArrayLength * Byte.SIZE);
return bitsMsg((long) byteArrayLength * Byte.SIZE);
}
public static void increment(byte[] a) {

View File

@ -6,12 +6,12 @@ import io.jsonwebtoken.impl.lang.CheckedFunction;
import io.jsonwebtoken.impl.lang.ValueGetter;
import io.jsonwebtoken.io.Encoders;
import io.jsonwebtoken.lang.Assert;
import io.jsonwebtoken.security.AeadAlgorithm;
import io.jsonwebtoken.security.DecryptionKeyRequest;
import io.jsonwebtoken.security.KeyAlgorithm;
import io.jsonwebtoken.security.KeyRequest;
import io.jsonwebtoken.security.KeyResult;
import io.jsonwebtoken.security.SecurityException;
import io.jsonwebtoken.security.SymmetricAeadAlgorithm;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
@ -34,7 +34,7 @@ public class AesGcmKeyAlgorithm extends AesAlgorithm implements KeyAlgorithm<Sec
Assert.notNull(request, "request cannot be null.");
final SecretKey kek = assertKey(request);
SymmetricAeadAlgorithm enc = Assert.notNull(request.getEncryptionAlgorithm(), "Request encryptionAlgorithm cannot be null.");
AeadAlgorithm enc = Assert.notNull(request.getEncryptionAlgorithm(), "Request encryptionAlgorithm cannot be null.");
final SecretKey cek = Assert.notNull(enc.generateKey(), "Request encryption algorithm cannot generate a null key.");
final byte[] iv = ensureInitializationVector(request);
final AlgorithmParameterSpec ivSpec = getIvSpec(iv);

View File

@ -2,12 +2,12 @@ package io.jsonwebtoken.impl.security;
import io.jsonwebtoken.impl.lang.CheckedFunction;
import io.jsonwebtoken.lang.Assert;
import io.jsonwebtoken.security.AeadAlgorithm;
import io.jsonwebtoken.security.DecryptionKeyRequest;
import io.jsonwebtoken.security.KeyAlgorithm;
import io.jsonwebtoken.security.KeyRequest;
import io.jsonwebtoken.security.KeyResult;
import io.jsonwebtoken.security.SecurityException;
import io.jsonwebtoken.security.SymmetricAeadAlgorithm;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
@ -28,7 +28,7 @@ public class AesWrapKeyAlgorithm extends AesAlgorithm implements KeyAlgorithm<Se
public KeyResult getEncryptionKey(KeyRequest<SecretKey> request) throws SecurityException {
Assert.notNull(request, "request cannot be null.");
final SecretKey kek = assertKey(request);
SymmetricAeadAlgorithm enc = Assert.notNull(request.getEncryptionAlgorithm(), "Request encryptionAlgorithm cannot be null.");
AeadAlgorithm enc = Assert.notNull(request.getEncryptionAlgorithm(), "Request encryptionAlgorithm cannot be null.");
final SecretKey cek = enc.generateKey();
Assert.notNull(cek, "Request encryption algorithm cannot generate a null key.");

View File

@ -1,29 +1,29 @@
package io.jsonwebtoken.impl.security;
import io.jsonwebtoken.security.AeadRequest;
import io.jsonwebtoken.security.InitializationVectorSupplier;
import io.jsonwebtoken.security.SymmetricAeadRequest;
import javax.crypto.SecretKey;
import java.security.Provider;
import java.security.SecureRandom;
public class DefaultSymmetricAeadRequest extends DefaultCryptoRequest<byte[], SecretKey> implements SymmetricAeadRequest, InitializationVectorSupplier {
public class DefaultAeadRequest extends DefaultCryptoRequest<byte[], SecretKey> implements AeadRequest, InitializationVectorSupplier {
private final byte[] IV;
private final byte[] AAD;
DefaultSymmetricAeadRequest(Provider provider, SecureRandom secureRandom, byte[] data, SecretKey key, byte[] aad, byte[] iv) {
DefaultAeadRequest(Provider provider, SecureRandom secureRandom, byte[] data, SecretKey key, byte[] aad, byte[] iv) {
super(provider, secureRandom, data, key);
this.AAD = aad;
this.IV = iv;
}
public DefaultSymmetricAeadRequest(Provider provider, SecureRandom secureRandom, byte[] data, SecretKey key, byte[] aad) {
public DefaultAeadRequest(Provider provider, SecureRandom secureRandom, byte[] data, SecretKey key, byte[] aad) {
this(provider, secureRandom, data, key, aad, null);
}
public DefaultSymmetricAeadRequest(byte[] data, SecretKey key, byte[] aad) {
public DefaultAeadRequest(byte[] data, SecretKey key, byte[] aad) {
this(null, null, data, key, aad, null);
}

View File

@ -2,13 +2,13 @@ package io.jsonwebtoken.impl.security;
import io.jsonwebtoken.lang.Assert;
import io.jsonwebtoken.security.AeadResult;
import io.jsonwebtoken.security.DecryptSymmetricAeadRequest;
import io.jsonwebtoken.security.DecryptAeadRequest;
import javax.crypto.SecretKey;
import java.security.Provider;
import java.security.SecureRandom;
public class DefaultAeadResult extends DefaultSymmetricAeadRequest implements AeadResult, DecryptSymmetricAeadRequest {
public class DefaultAeadResult extends DefaultAeadRequest implements AeadResult, DecryptAeadRequest {
private final byte[] TAG;

View File

@ -1,8 +1,8 @@
package io.jsonwebtoken.impl.security;
import io.jsonwebtoken.JweHeader;
import io.jsonwebtoken.security.AeadAlgorithm;
import io.jsonwebtoken.security.DecryptionKeyRequest;
import io.jsonwebtoken.security.SymmetricAeadAlgorithm;
import java.security.Key;
import java.security.Provider;
@ -12,7 +12,7 @@ public class DefaultDecryptionKeyRequest<K extends Key> extends DefaultKeyReques
private final byte[] payload;
public DefaultDecryptionKeyRequest(Provider provider, SecureRandom secureRandom, K key, JweHeader header, SymmetricAeadAlgorithm encryptionAlgorithm, byte[] payload) {
public DefaultDecryptionKeyRequest(Provider provider, SecureRandom secureRandom, K key, JweHeader header, AeadAlgorithm encryptionAlgorithm, byte[] payload) {
super(provider, secureRandom, key, header, encryptionAlgorithm);
this.payload = payload;
}

View File

@ -2,8 +2,8 @@ package io.jsonwebtoken.impl.security;
import io.jsonwebtoken.JweHeader;
import io.jsonwebtoken.lang.Assert;
import io.jsonwebtoken.security.AeadAlgorithm;
import io.jsonwebtoken.security.KeyRequest;
import io.jsonwebtoken.security.SymmetricAeadAlgorithm;
import java.security.Key;
import java.security.Provider;
@ -12,12 +12,12 @@ import java.security.SecureRandom;
public class DefaultKeyRequest<K extends Key> extends DefaultKeyedRequest<K> implements KeyRequest<K> {
private final JweHeader header;
private final SymmetricAeadAlgorithm encryptionAlgorithm;
private final AeadAlgorithm encryptionAlgorithm;
public DefaultKeyRequest(Provider provider, SecureRandom secureRandom, K key, JweHeader header, SymmetricAeadAlgorithm encryptionAlgorithm) {
public DefaultKeyRequest(Provider provider, SecureRandom secureRandom, K key, JweHeader header, AeadAlgorithm encryptionAlgorithm) {
super(provider, secureRandom, key);
this.header = Assert.notNull(header, "JweHeader cannot be null.");
this.encryptionAlgorithm = Assert.notNull(encryptionAlgorithm, "SymmetricAeadAlgorithm argument cannot be null.");
this.encryptionAlgorithm = Assert.notNull(encryptionAlgorithm, "AeadAlgorithm argument cannot be null.");
}
@Override
@ -26,7 +26,7 @@ public class DefaultKeyRequest<K extends Key> extends DefaultKeyedRequest<K> imp
}
@Override
public SymmetricAeadAlgorithm getEncryptionAlgorithm() {
public AeadAlgorithm getEncryptionAlgorithm() {
return this.encryptionAlgorithm;
}
}

View File

@ -1,5 +1,6 @@
package io.jsonwebtoken.impl.security;
import io.jsonwebtoken.lang.Assert;
import io.jsonwebtoken.lang.Objects;
import io.jsonwebtoken.security.PbeKey;
@ -8,27 +9,17 @@ public class DefaultPbeKey implements PbeKey {
private static final String RAW_FORMAT = "RAW";
private static final String NONE_ALGORITHM = "NONE";
private volatile boolean destroyed = false;
private volatile boolean destroyed;
private final char[] chars;
//private final byte[] bytes;
private final int workFactor;
private final int iterations;
// private static byte[] toBytes(char[] chars) {
// ByteBuffer buf = StandardCharsets.UTF_8.encode(CharBuffer.wrap(chars));
// byte[] bytes = new byte[buf.limit()];
// buf.get(bytes);
// return bytes;
// }
public DefaultPbeKey(char[] password, int workFactor) {
boolean empty = Objects.isEmpty(password);
this.chars = empty ? new char[0] : password.clone();
//this.bytes = empty ? new byte[0] : toBytes(this.chars);
if (workFactor < 0) {
String msg = "workFactor cannot be negative. Value: " + workFactor;
public DefaultPbeKey(char[] password, int iterations) {
if (iterations <= 0) {
String msg = "iterations must be a positive integer. Value: " + iterations;
throw new IllegalArgumentException(msg);
}
this.workFactor = workFactor;
this.iterations = iterations;
this.chars = Assert.notEmpty(password, "Password character array cannot be null or empty.");
}
private void assertActive() {
@ -45,8 +36,8 @@ public class DefaultPbeKey implements PbeKey {
}
@Override
public int getWorkFactor() {
return this.workFactor;
public int getIterations() {
return this.iterations;
}
@Override
@ -62,16 +53,11 @@ public class DefaultPbeKey implements PbeKey {
@Override
public byte[] getEncoded() {
throw new UnsupportedOperationException("getEncoded is not supported for PbeKey instances.");
//assertActive();
//return this.bytes.clone();
}
@Override
public void destroy() {
// if (bytes != null) {
// java.util.Arrays.fill(bytes, (byte) 0);
// }
if (chars != null) {
if (!destroyed && chars != null) {
java.util.Arrays.fill(chars, '\u0000');
}
this.destroyed = true;
@ -91,7 +77,7 @@ public class DefaultPbeKey implements PbeKey {
public boolean equals(Object obj) {
if (obj instanceof DefaultPbeKey) {
DefaultPbeKey other = (DefaultPbeKey) obj;
return this.workFactor == other.workFactor &&
return this.iterations == other.iterations &&
Objects.nullSafeEquals(this.chars, other.chars);
}
return false;
@ -99,6 +85,6 @@ public class DefaultPbeKey implements PbeKey {
@Override
public String toString() {
return "password=<redacted>, workFactor=" + this.workFactor;
return "password=<redacted>, iterations=" + this.iterations;
}
}

View File

@ -4,93 +4,26 @@ import io.jsonwebtoken.lang.Assert;
import io.jsonwebtoken.security.PbeKey;
import io.jsonwebtoken.security.PbeKeyBuilder;
import javax.crypto.interfaces.PBEKey;
import javax.security.auth.Destroyable;
//
// MAINTAINER NOTE:
//
// If editing/modifying this class, DO NOT attempt to call jcaKey.getPassword(): doing so creates a clone of that
// character array. There is no need to create copies of sensitive data (that we would be responsible for cleaning up)
// since the JcaPbeKey implementation will just delegate to the jcaKey as needed.
//
public class DefaultPbeKeyBuilder<K extends PbeKey> implements PbeKeyBuilder<K>, Destroyable {
public class DefaultPbeKeyBuilder implements PbeKeyBuilder<PbeKey> {
private char[] password;
private int workFactor;
private PBEKey jcaKey;
private volatile boolean destroyed;
private static char[] assertPassword(char[] password) {
Assert.notEmpty(password, "Password cannot be null or empty.");
return password;
}
private static int assertWorkFactor(int workFactor) {
if (workFactor < 0) {
String msg = "workFactor cannot be negative.";
throw new IllegalArgumentException(msg);
}
return workFactor;
}
private int iterations;
@Override
public PbeKeyBuilder<K> forKey(PBEKey jcaKey) {
this.jcaKey = Assert.notNull(jcaKey, "PBEKey cannot be null.");
public DefaultPbeKeyBuilder setPassword(final char[] password) {
this.password = Assert.notEmpty(password, "password cannot be null or empty.");
return this;
}
@Override
public PbeKeyBuilder<K> setPassword(String password) {
return setPassword(Assert.notNull(password, "password cannot be null.").toCharArray());
}
@Override
public DefaultPbeKeyBuilder<K> setPassword(char[] password) {
this.password = password;
public DefaultPbeKeyBuilder setIterations(final int iterations) {
Assert.isTrue(iterations > 0, "iterations must be a positive integer.");
this.iterations = iterations;
return this;
}
@Override
public DefaultPbeKeyBuilder<K> setWorkFactor(int workFactor) {
this.workFactor = workFactor;
return this;
}
@Override
public void destroy() {
if (this.password != null) {
destroyed = true;
java.util.Arrays.fill(this.password, '\u0000');
}
}
@Override
public boolean isDestroyed() {
return destroyed;
}
private void assertActive() {
if (destroyed) {
String msg = "This PbeKeyBuilder has been destroyed in order to clean/zero-out internal password " +
"arrays for safety. Please use a new builder for each PbeKey instance you need to create.";
throw new IllegalStateException(msg);
}
}
@SuppressWarnings("unchecked")
@Override
public K build() {
try {
if (this.jcaKey != null) {
return (K) new JcaPbeKey(this.jcaKey);
}
assertActive();
assertPassword(this.password);
assertWorkFactor(this.workFactor);
return (K) new DefaultPbeKey(this.password, this.workFactor);
} finally {
destroy();
}
public PbeKey build() {
return new DefaultPbeKey(this.password, this.iterations);
}
}

View File

@ -2,12 +2,12 @@ package io.jsonwebtoken.impl.security;
import io.jsonwebtoken.impl.lang.CheckedFunction;
import io.jsonwebtoken.lang.Assert;
import io.jsonwebtoken.security.AeadAlgorithm;
import io.jsonwebtoken.security.DecryptionKeyRequest;
import io.jsonwebtoken.security.KeyRequest;
import io.jsonwebtoken.security.KeyResult;
import io.jsonwebtoken.security.RsaKeyAlgorithm;
import io.jsonwebtoken.security.SecurityException;
import io.jsonwebtoken.security.SymmetricAeadAlgorithm;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
@ -35,7 +35,7 @@ public class DefaultRsaKeyAlgorithm<E extends RSAKey & PublicKey, D extends RSAK
public KeyResult getEncryptionKey(final KeyRequest<E> request) throws SecurityException {
Assert.notNull(request, "Request cannot be null.");
final E kek = Assert.notNull(request.getKey(), "Request key encryption key cannot be null.");
SymmetricAeadAlgorithm enc = Assert.notNull(request.getEncryptionAlgorithm(), "Request encryptionAlgorithm cannot be null.");
AeadAlgorithm enc = Assert.notNull(request.getEncryptionAlgorithm(), "Request encryptionAlgorithm cannot be null.");
final SecretKey cek = Assert.notNull(enc.generateKey(), "Request encryption algorithm cannot generate a null key.");
byte[] ciphertext = execute(request, Cipher.class, new CheckedFunction<Cipher, byte[]>() {

View File

@ -46,6 +46,8 @@ class DispatchingJwkFactory implements JwkFactory<Key, Jwk<Key>> {
@Override
public Jwk<Key> createJwk(JwkContext<Key> ctx) {
Assert.notNull(ctx, "JwkContext cannot be null.");
final Key key = ctx.getKey();
final String kty = Strings.clean(ctx.getType());

View File

@ -4,7 +4,7 @@ import io.jsonwebtoken.UnsupportedJwtException;
import io.jsonwebtoken.impl.IdRegistry;
import io.jsonwebtoken.impl.lang.Registry;
import io.jsonwebtoken.lang.Collections;
import io.jsonwebtoken.security.SymmetricAeadAlgorithm;
import io.jsonwebtoken.security.AeadAlgorithm;
import java.util.Collection;
@ -16,11 +16,11 @@ public class EncryptionAlgorithmsBridge {
}
//For parser implementation - do not expose outside the impl module:
public static final Registry<String, SymmetricAeadAlgorithm> REGISTRY;
public static final Registry<String, AeadAlgorithm> REGISTRY;
static {
REGISTRY = new IdRegistry<>(Collections.of(
(SymmetricAeadAlgorithm) new HmacAesAeadAlgorithm(128),
(AeadAlgorithm) new HmacAesAeadAlgorithm(128),
new HmacAesAeadAlgorithm(192),
new HmacAesAeadAlgorithm(256),
new GcmAesAeadAlgorithm(128),
@ -29,18 +29,18 @@ public class EncryptionAlgorithmsBridge {
));
}
public static Collection<SymmetricAeadAlgorithm> values() {
public static Collection<AeadAlgorithm> values() {
return REGISTRY.values();
}
public static SymmetricAeadAlgorithm findById(String id) {
public static AeadAlgorithm findById(String id) {
return REGISTRY.apply(id);
}
public static SymmetricAeadAlgorithm forId(String id) {
SymmetricAeadAlgorithm alg = findById(id);
public static AeadAlgorithm forId(String id) {
AeadAlgorithm alg = findById(id);
if (alg == null) {
String msg = "Unrecognized JWA SymmetricAeadAlgorithm identifier: " + id;
String msg = "Unrecognized JWA AeadAlgorithm identifier: " + id;
throw new UnsupportedJwtException(msg);
}
return alg;

View File

@ -5,11 +5,11 @@ import io.jsonwebtoken.impl.lang.CheckedFunction;
import io.jsonwebtoken.lang.Arrays;
import io.jsonwebtoken.lang.Assert;
import io.jsonwebtoken.lang.RuntimeEnvironment;
import io.jsonwebtoken.security.AeadAlgorithm;
import io.jsonwebtoken.security.AeadRequest;
import io.jsonwebtoken.security.AeadResult;
import io.jsonwebtoken.security.DecryptSymmetricAeadRequest;
import io.jsonwebtoken.security.DecryptAeadRequest;
import io.jsonwebtoken.security.PayloadSupplier;
import io.jsonwebtoken.security.SymmetricAeadAlgorithm;
import io.jsonwebtoken.security.SymmetricAeadRequest;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
@ -18,7 +18,7 @@ import java.security.spec.AlgorithmParameterSpec;
/**
* @since JJWT_RELEASE_VERSION
*/
public class GcmAesAeadAlgorithm extends AesAlgorithm implements SymmetricAeadAlgorithm {
public class GcmAesAeadAlgorithm extends AesAlgorithm implements AeadAlgorithm {
//TODO: Remove this static block when JDK 7 support is removed
// JDK <= 7 does not support AES GCM mode natively and so BouncyCastle is required
@ -33,7 +33,7 @@ public class GcmAesAeadAlgorithm extends AesAlgorithm implements SymmetricAeadAl
}
@Override
public AeadResult encrypt(final SymmetricAeadRequest req) throws SecurityException {
public AeadResult encrypt(final AeadRequest req) throws SecurityException {
Assert.notNull(req, "Request cannot be null.");
final SecretKey key = assertKey(req);
@ -65,7 +65,7 @@ public class GcmAesAeadAlgorithm extends AesAlgorithm implements SymmetricAeadAl
}
@Override
public PayloadSupplier<byte[]> decrypt(final DecryptSymmetricAeadRequest req) throws SecurityException {
public PayloadSupplier<byte[]> decrypt(final DecryptAeadRequest req) throws SecurityException {
Assert.notNull(req, "Request cannot be null.");
final SecretKey key = assertKey(req);

View File

@ -1,15 +1,16 @@
package io.jsonwebtoken.impl.security;
import io.jsonwebtoken.impl.lang.Bytes;
import io.jsonwebtoken.impl.lang.CheckedFunction;
import io.jsonwebtoken.lang.Assert;
import io.jsonwebtoken.security.AeadAlgorithm;
import io.jsonwebtoken.security.AeadRequest;
import io.jsonwebtoken.security.AeadResult;
import io.jsonwebtoken.security.CryptoRequest;
import io.jsonwebtoken.security.DecryptSymmetricAeadRequest;
import io.jsonwebtoken.security.DecryptAeadRequest;
import io.jsonwebtoken.security.PayloadSupplier;
import io.jsonwebtoken.security.SignatureException;
import io.jsonwebtoken.security.SignatureRequest;
import io.jsonwebtoken.security.SymmetricAeadAlgorithm;
import io.jsonwebtoken.security.SymmetricAeadRequest;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
@ -21,7 +22,7 @@ import java.util.Arrays;
/**
* @since JJWT_RELEASE_VERSION
*/
public class HmacAesAeadAlgorithm extends AesAlgorithm implements SymmetricAeadAlgorithm {
public class HmacAesAeadAlgorithm extends AesAlgorithm implements AeadAlgorithm {
private static final String TRANSFORMATION_STRING = "AES/CBC/PKCS5Padding";
@ -40,9 +41,8 @@ public class HmacAesAeadAlgorithm extends AesAlgorithm implements SymmetricAeadA
this.SIGALG = sigAlg;
}
@SuppressWarnings("unused") //Used via reflection by io.jsonwebtoken.security.EncryptionAlgorithms
public HmacAesAeadAlgorithm(int keyLength) {
this(id(keyLength), new MacSignatureAlgorithm(id(keyLength), "HmacSHA" + digestLength(keyLength), keyLength));
public HmacAesAeadAlgorithm(int keyBitLength) {
this(id(keyBitLength), new MacSignatureAlgorithm(id(keyBitLength), "HmacSHA" + digestLength(keyBitLength), keyBitLength));
}
@Override
@ -56,7 +56,7 @@ public class HmacAesAeadAlgorithm extends AesAlgorithm implements SymmetricAeadA
}
@Override
public AeadResult encrypt(final SymmetricAeadRequest req) {
public AeadResult encrypt(final AeadRequest req) {
Assert.notNull(req, "Request cannot be null.");
@ -89,7 +89,7 @@ public class HmacAesAeadAlgorithm extends AesAlgorithm implements SymmetricAeadA
long aadLength = io.jsonwebtoken.lang.Arrays.length(aad);
long aadLengthInBits = aadLength * Byte.SIZE;
long aadLengthInBitsAsUnsignedInt = aadLengthInBits & 0xffffffffL;
byte[] AL = toBytes(aadLengthInBitsAsUnsignedInt);
byte[] AL = Bytes.toBytes(aadLengthInBitsAsUnsignedInt);
byte[] toHash = new byte[(int) aadLength + iv.length + ciphertext.length + AL.length];
@ -113,18 +113,8 @@ public class HmacAesAeadAlgorithm extends AesAlgorithm implements SymmetricAeadA
return assertTag(Arrays.copyOfRange(digest, 0, macKeyBytes.length));
}
private static byte[] toBytes(long l) {
byte[] b = new byte[8];
for (int i = 7; i > 0; i--) {
b[i] = (byte) l;
l >>>= 8;
}
b[0] = (byte) l;
return b;
}
@Override
public PayloadSupplier<byte[]> decrypt(final DecryptSymmetricAeadRequest req) {
public PayloadSupplier<byte[]> decrypt(final DecryptAeadRequest req) {
Assert.notNull(req, "Request cannot be null.");

View File

@ -20,7 +20,7 @@ public class JcaPbeKey implements PbeKey {
}
@Override
public int getWorkFactor() {
public int getIterations() {
return this.jcaKey.getIterationCount();
}

View File

@ -7,6 +7,7 @@ import io.jsonwebtoken.impl.IdRegistry;
import io.jsonwebtoken.impl.lang.CheckedFunction;
import io.jsonwebtoken.impl.lang.Registry;
import io.jsonwebtoken.lang.Collections;
import io.jsonwebtoken.security.AeadAlgorithm;
import io.jsonwebtoken.security.DecryptionKeyRequest;
import io.jsonwebtoken.security.EncryptionAlgorithms;
import io.jsonwebtoken.security.KeyAlgorithm;
@ -15,7 +16,6 @@ import io.jsonwebtoken.security.KeyResult;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.PbeKey;
import io.jsonwebtoken.security.SecurityException;
import io.jsonwebtoken.security.SymmetricAeadAlgorithm;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
@ -101,7 +101,7 @@ public final class KeyAlgorithmsBridge {
return new KeyAlgorithm<PbeKey, SecretKey>() {
@Override
public KeyResult getEncryptionKey(KeyRequest<PbeKey> request) throws SecurityException {
int iterations = request.getKey().getWorkFactor();
int iterations = request.getKey().getIterations();
char[] password = request.getKey().getPassword();
try {
alg.deriveKey(factory, password, rfcSalt, iterations);
@ -148,7 +148,7 @@ public final class KeyAlgorithmsBridge {
final int PASSWORD_LENGTH = 8;
final JweHeader HEADER = new DefaultJweHeader(); // not used during execution, needed to satisfy API call.
final SymmetricAeadAlgorithm ENC_ALG = EncryptionAlgorithms.A128GCM; // not used, needed to satisfy API
final AeadAlgorithm ENC_ALG = EncryptionAlgorithms.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:
@ -161,7 +161,7 @@ public final class KeyAlgorithmsBridge {
for (int i = 0; points.size() < NUM_SAMPLES; i++) {
char[] password = randomChars(PASSWORD_LENGTH);
PbeKey pbeKey = Keys.forPbe().setPassword(password).setWorkFactor(workFactor).build();
PbeKey pbeKey = Keys.forPbe().setPassword(password).setIterations(workFactor).build();
KeyRequest<PbeKey> request = new DefaultKeyRequest<>(null, null, pbeKey, HEADER, ENC_ALG);
long start = System.currentTimeMillis();

View File

@ -3,6 +3,8 @@ package io.jsonwebtoken.impl.security;
import io.jsonwebtoken.security.PbeKey;
import io.jsonwebtoken.security.PbeKeyBuilder;
import javax.crypto.interfaces.PBEKey;
@SuppressWarnings({"unused"}) // reflection bridge class for the io.jsonwebtoken.security.Keys implementation
public class KeysBridge {
@ -10,7 +12,11 @@ public class KeysBridge {
private KeysBridge() {
}
public static PbeKey toPbeKey(PBEKey key) {
return new JcaPbeKey(key);
}
public static PbeKeyBuilder<PbeKey> forPbe() {
return new DefaultPbeKeyBuilder<>();
return new DefaultPbeKeyBuilder();
}
}

View File

@ -126,7 +126,7 @@ public class Pbes2HsAkwAlgorithm extends CryptoAlgorithm implements KeyAlgorithm
Assert.notNull(request, "request cannot be null.");
final PbeKey pbeKey = Assert.notNull(request.getKey(), "request.getKey() cannot be null.");
final int iterations = assertIterations(pbeKey.getWorkFactor());
final int iterations = assertIterations(pbeKey.getIterations());
byte[] inputSalt = generateInputSalt(request);
final byte[] rfcSalt = toRfcSalt(inputSalt);
final String p2s = Encoders.BASE64URL.encode(inputSalt);

View File

@ -15,6 +15,7 @@
*/
package io.jsonwebtoken
import io.jsonwebtoken.SignatureAlgorithm
import io.jsonwebtoken.impl.DefaultHeader
import io.jsonwebtoken.impl.DefaultJweHeader
import io.jsonwebtoken.impl.DefaultJwsHeader
@ -25,9 +26,7 @@ import io.jsonwebtoken.impl.lang.Services
import io.jsonwebtoken.io.Encoders
import io.jsonwebtoken.io.Serializer
import io.jsonwebtoken.lang.Strings
import io.jsonwebtoken.security.Keys
import io.jsonwebtoken.security.SignatureAlgorithms
import io.jsonwebtoken.security.WeakKeyException
import io.jsonwebtoken.security.*
import org.junit.Test
import javax.crypto.Mac
@ -37,6 +36,7 @@ import java.security.Key
import java.security.KeyPair
import java.security.PrivateKey
import java.security.PublicKey
import java.security.interfaces.RSAPrivateKey
import static org.junit.Assert.*
@ -815,5 +815,13 @@ class JwtsTest {
//noinspection GrEqualsBetweenInconvertibleTypes
assert token.body == claims
}
void testFoo() {
RSAPrivateKey key;
Jwts.jweBuilder()
.encryptWith(EncryptionAlgorithms.A128GCM)
.usingKey(key)
.fromKeyAlgorithm(KeyAlgorithms.PBES2_HS256_A128KW.withIterations(1203023))
}
}

View File

@ -75,7 +75,7 @@ class DefaultJweBuilderTest {
for( KeyAlgorithm<? extends Key,? extends Key> keyAlg : KeyAlgorithms.values() ) {
for(SymmetricAeadAlgorithm encAlg : EncryptionAlgorithms.values() ) {
for(AeadAlgorithm encAlg : EncryptionAlgorithms.values() ) {
Key kek = encAlg.generateKey();
String jwe = builder().setSubject('joe').encryptWith(encAlg).withKeyFrom(kek, keyAlg).compact()
}

View File

@ -1,6 +1,6 @@
package io.jsonwebtoken.impl.security
import io.jsonwebtoken.lang.Assert
import io.jsonwebtoken.security.Jwks
import io.jsonwebtoken.security.RsaPublicJwkBuilder
import io.jsonwebtoken.security.SignatureAlgorithms
@ -10,12 +10,14 @@ import java.security.cert.X509Certificate
import java.security.interfaces.RSAPrivateKey
import java.security.interfaces.RSAPublicKey
import static org.junit.Assert.*
import static org.junit.Assert.assertEquals
import static org.junit.Assert.assertSame
class AbstractAsymmetricJwkBuilderTest {
private static final X509Certificate CERT = CertUtils.readTestCertificate(SignatureAlgorithms.RS256)
private static final RSAPublicKey PUB_KEY = (RSAPublicKey)CERT.getPublicKey();
private static final List<X509Certificate> CHAIN = [CERT]
private static final RSAPublicKey PUB_KEY = (RSAPublicKey) CERT.getPublicKey()
private static RsaPublicJwkBuilder builder() {
return Jwks.builder().setKey(PUB_KEY)
@ -28,9 +30,9 @@ class AbstractAsymmetricJwkBuilderTest {
assertEquals val, jwk.getPublicKeyUse()
assertEquals val, jwk.use
def privateKey = CertUtils.readTestPrivateKey(SignatureAlgorithms.RS256);
def privateKey = CertUtils.readTestPrivateKey(SignatureAlgorithms.RS256)
jwk = builder().setPublicKeyUse(val).setPrivateKey((RSAPrivateKey)privateKey).build()
jwk = builder().setPublicKeyUse(val).setPrivateKey((RSAPrivateKey) privateKey).build()
assertEquals val, jwk.getPublicKeyUse()
assertEquals val, jwk.use
}
@ -38,28 +40,25 @@ class AbstractAsymmetricJwkBuilderTest {
@Test
void testX509Url() {
def val = new URI(UUID.randomUUID().toString())
assertEquals val, builder().setX509Url(val).build().getX509Url()
assertSame val, builder().setX509Url(val).build().getX509Url()
}
@Test
void testX509CertificateChain() {
def a = UUID.randomUUID().toString()
def b = UUID.randomUUID().toString()
def val = [a, b] as List<String>
assertEquals val, builder().setX509CertificateChain(val).build().getX509CertificateChain()
assertEquals CHAIN, builder().setX509CertificateChain(CHAIN).build().getX509CertificateChain()
}
@Test
void testX509CertificateSha1Thumbprint() {
def val = UUID.randomUUID().toString()
assertEquals val, builder().setX509CertificateSha1Thumbprint(val).build().getX509CertificateSha1Thumbprint()
def jwk = builder().setX509CertificateChain(CHAIN).withX509Sha1Thumbprint(true).build()
Assert.notEmpty(jwk.getX509CertificateSha1Thumbprint())
Assert.hasText(jwk.get(AbstractAsymmetricJwk.X509_SHA1_THUMBPRINT) as String)
}
@Test
void testX509CertificateSha256Thumbprint() {
def val = UUID.randomUUID().toString()
assertEquals val, builder().setX509CertificateSha256Thumbprint(val).build().getX509CertificateSha256Thumbprint()
def jwk = builder().setX509CertificateChain(CHAIN).withX509Sha256Thumbprint(true).build()
Assert.notEmpty(jwk.getX509CertificateSha256Thumbprint())
Assert.hasText(jwk.get(AbstractAsymmetricJwk.X509_SHA256_THUMBPRINT) as String)
}
}

View File

@ -5,7 +5,8 @@ import org.junit.Test
import java.security.SecureRandom
import static org.junit.Assert.*
import static org.junit.Assert.assertSame
import static org.junit.Assert.fail
/**
* @since JJWT_RELEASE_VERSION
@ -17,26 +18,6 @@ class AesAlgorithmTest {
new TestAesAlgorithm('foo', 'foo', 0)
}
@Test
void testDoEncryptFailure() {
def alg = new TestAesAlgorithm('foo', 'foo', 128) {
@Override
AeadResult encrypt(SymmetricAeadRequest symmetricAeadRequest) throws Exception {
throw new IllegalArgumentException('broken')
}
}
def req = new DefaultSymmetricAeadRequest('bar'.getBytes(), alg.generateKey(), 'foo'.getBytes());
try {
alg.encrypt(req)
} catch (SecurityException expected) {
assertTrue expected.getCause() instanceof IllegalArgumentException
assertTrue expected.getCause().getMessage().equals('broken')
}
}
@Test
void testAssertKeyLength() {
@ -60,26 +41,26 @@ class AesAlgorithmTest {
def secureRandom = new SecureRandom()
def req = new DefaultSymmetricAeadRequest(null, secureRandom, 'data'.getBytes(), alg.generateKey(), 'aad'.getBytes())
def req = new DefaultAeadRequest(null, secureRandom, 'data'.getBytes(), alg.generateKey(), 'aad'.getBytes())
def returnedSecureRandom = alg.ensureSecureRandom(req)
assertSame(secureRandom, returnedSecureRandom)
}
static class TestAesAlgorithm extends AesAlgorithm implements SymmetricAeadAlgorithm {
static class TestAesAlgorithm extends AesAlgorithm implements AeadAlgorithm {
TestAesAlgorithm(String name, String transformationString, int requiredKeyLengthInBits) {
super(name, transformationString, requiredKeyLengthInBits)
}
@Override
AeadResult encrypt(SymmetricAeadRequest symmetricAeadRequest) {
AeadResult encrypt(AeadRequest symmetricAeadRequest) {
return null
}
@Override
PayloadSupplier<byte[]> decrypt(DecryptSymmetricAeadRequest symmetricAeadDecryptionRequest) {
PayloadSupplier<byte[]> decrypt(DecryptAeadRequest symmetricAeadDecryptionRequest) {
return null
}
}

View File

@ -19,7 +19,7 @@ import static org.junit.Assert.*
class AesGcmKeyAlgorithmTest {
/**
* This tests asserts that our SymmetricAeadAlgorithm implementation and the JCA 'AES/GCM/NoPadding' wrap algorithm
* This tests asserts that our AeadAlgorithm implementation and the JCA 'AES/GCM/NoPadding' wrap algorithm
* produce the exact same values. This should be the case when the transformation is identical, even though
* one uses Cipher.WRAP_MODE and the other uses a raw plaintext byte array.
*/
@ -52,7 +52,7 @@ class AesGcmKeyAlgorithmTest {
System.arraycopy(jcaResult, ciphertextLength, tag, 0, 16)
def resultA = new DefaultAeadResult(null, null, ciphertext, kek, null, tag, iv)
def encRequest = new DefaultSymmetricAeadRequest(null, null, cek.getEncoded(), kek, null, iv)
def encRequest = new DefaultAeadRequest(null, null, cek.getEncoded(), kek, null, iv)
def encResult = EncryptionAlgorithms.A256GCM.encrypt(encRequest)
assertArrayEquals resultA.digest, encResult.digest

View File

@ -2,11 +2,14 @@ package io.jsonwebtoken.impl.security
import io.jsonwebtoken.impl.DefaultJweHeader
import io.jsonwebtoken.lang.Arrays
import io.jsonwebtoken.security.DecryptionKeyRequest
import io.jsonwebtoken.security.EncryptionAlgorithms
import org.junit.Test
import javax.crypto.spec.SecretKeySpec
import java.security.Key
import static org.easymock.EasyMock.*
import static org.junit.Assert.assertEquals
import static org.junit.Assert.assertSame
@ -21,7 +24,7 @@ class DirectKeyAlgorithmTest {
void testGetEncryptionKey() {
def alg = new DirectKeyAlgorithm()
def key = new SecretKeySpec(new byte[1], "AES")
def request = new DefaultKeyRequest(null, null, key, key, new DefaultJweHeader(), null)
def request = new DefaultKeyRequest(null, null, key, new DefaultJweHeader(), EncryptionAlgorithms.A128GCM)
def result = alg.getEncryptionKey(request)
assertSame key, result.getKey()
assertEquals 0, Arrays.length(result.getPayload()) //must not have an encrypted key
@ -35,7 +38,7 @@ class DirectKeyAlgorithmTest {
@Test(expected = IllegalArgumentException)
void testGetEncryptionKeyWithNullRequestKey() {
def key = new SecretKeySpec(new byte[1], "AES")
def request = new DefaultKeyRequest(null, null, key, key, new DefaultJweHeader(), null) {
def request = new DefaultKeyRequest(null, null, key, new DefaultJweHeader(), EncryptionAlgorithms.A128GCM) {
@Override
Key getKey() {
return null
@ -47,9 +50,12 @@ class DirectKeyAlgorithmTest {
@Test
void testGetDecryptionKey() {
def alg = new DirectKeyAlgorithm()
def key = new SecretKeySpec(new byte[1], "AES")
def request = new DefaultKeyRequest(null, null, key, key, new DefaultJweHeader(), null)
def result = alg.getDecryptionKey(request)
DecryptionKeyRequest req = createMock(DecryptionKeyRequest)
def key = EncryptionAlgorithms.A128GCM.generateKey()
expect(req.getKey()).andReturn(key)
replay(req)
def result = alg.getDecryptionKey(req)
verify(req)
assertSame key, result
}
@ -60,13 +66,9 @@ class DirectKeyAlgorithmTest {
@Test(expected = IllegalArgumentException)
void testGetDecryptionKeyWithNullRequestKey() {
def key = new SecretKeySpec(new byte[1], "AES")
def request = new DefaultKeyRequest(null, null, key, key, new DefaultJweHeader(), null) {
@Override
Key getKey() {
return null
}
}
new DirectKeyAlgorithm().getDecryptionKey(request)
DecryptionKeyRequest req = createMock(DecryptionKeyRequest)
expect(req.getKey()).andReturn(null)
replay(req)
new DirectKeyAlgorithm().getDecryptionKey(req)
}
}

View File

@ -3,7 +3,6 @@ package io.jsonwebtoken.impl.security
import io.jsonwebtoken.io.Encoders
import io.jsonwebtoken.security.EcPrivateJwk
import io.jsonwebtoken.security.EcPublicJwk
import io.jsonwebtoken.security.InvalidKeyException
import io.jsonwebtoken.security.SignatureAlgorithms
import io.jsonwebtoken.security.UnsupportedKeyException
import org.junit.Ignore
@ -14,53 +13,31 @@ import java.security.KeyPair
import java.security.interfaces.ECPrivateKey
import java.security.interfaces.ECPublicKey
import static org.junit.Assert.assertEquals
import static org.junit.Assert.assertNotNull
import static org.junit.Assert.assertNull
import static org.junit.Assert.assertTrue
import static org.junit.Assert.fail
import static org.junit.Assert.*
class DispatchingJwkFactoryTest {
@Test
@Test(expected = IllegalArgumentException)
void testNullJwk() {
try {
new DispatchingJwkFactory().createJwk(null)
fail()
} catch (InvalidKeyException expected) {
assertEquals 'JWK map cannot be null or empty.', expected.message
}
new DispatchingJwkFactory().createJwk(null)
}
@Test
@Test(expected = IllegalArgumentException)
void testEmptyJwk() {
try {
new DispatchingJwkFactory().createJwk(new DefaultJwkContext<Key>())
fail()
} catch (InvalidKeyException expected) {
assertEquals 'JWK map cannot be null or empty.', expected.message
}
new DispatchingJwkFactory().createJwk(new DefaultJwkContext<Key>())
}
@Test
@Test(expected = UnsupportedKeyException)
void testUnknownKeyType() {
def ctx = new DefaultJwkContext();
ctx.put('kty', 'foo')
DispatchingJwkFactory factory = new DispatchingJwkFactory()
try {
factory.createJwk(ctx)
fail()
} catch (UnsupportedKeyException e) {
assertEquals 'Unrecognized JWK kty (key type) value: foo', e.getMessage()
}
new DispatchingJwkFactory().createJwk(ctx)
}
@Test
void testEcKeyPairToKey() {
def m = [
Map<String,String> m = [
'kty': 'EC',
'crv': 'P-256',
"x" : "gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0",
@ -83,7 +60,7 @@ class DispatchingJwkFactoryTest {
assertEquals jwk.d, d
//remove the 'd' mapping to represent only a public key:
m = m.remove(DefaultEcPrivateJwk.D)
m.remove(DefaultEcPrivateJwk.D)
ctx = new DefaultJwkContext()
ctx.putAll(m)

View File

@ -46,7 +46,7 @@ class GcmAesAeadAlgorithmTest {
def alg = EncryptionAlgorithms.A256GCM
def req = new DefaultSymmetricAeadRequest(null, null, P, KEY, AAD, IV)
def req = new DefaultAeadRequest(null, null, P, KEY, AAD, IV)
def result = alg.encrypt(req)

View File

@ -5,7 +5,6 @@ import io.jsonwebtoken.security.SignatureException
import org.junit.Test
import javax.crypto.SecretKey
import javax.crypto.spec.SecretKeySpec
import static org.junit.Assert.assertEquals
@ -18,7 +17,8 @@ class HmacAesAeadAlgorithmTest {
void testGenerateKey() {
def alg = EncryptionAlgorithms.A128CBC_HS256
SecretKey key = alg.generateKey();
assertEquals alg.requiredKeyByteLength, key.getEncoded().length
int algKeyByteLength = (alg.keyBitLength * 2) / Byte.SIZE
assertEquals algKeyByteLength, key.getEncoded().length
}
@Test(expected = SignatureException)
@ -30,7 +30,7 @@ class HmacAesAeadAlgorithmTest {
def plaintext = "Hello World! Nice to meet you!".getBytes("UTF-8")
def req = new DefaultSymmetricAeadRequest(null, null, plaintext, key, null)
def req = new DefaultAeadRequest(null, null, plaintext, key, null)
def result = alg.encrypt(req);
def realTag = result.getDigest();
@ -42,46 +42,4 @@ class HmacAesAeadAlgorithmTest {
def dreq = new DefaultAeadResult(null, null, result.getPayload(), key, null, fakeTag, result.getInitializationVector())
alg.decrypt(dreq)
}
@Test(expected = IllegalStateException)
void testGenerateKeyWithWeakSigAlgKey() {
final byte[] bytes = new byte[24] // less than 32 bytes/256 bits
Randoms.secureRandom().nextBytes(bytes)
def sigAlg = new MacSignatureAlgorithm('HS256', 'HmacSHA256', 256) {
@Override
SecretKey generateKey() {
return new SecretKeySpec(bytes, 'HmacSHA256')
}
}
def alg = new HmacAesAeadAlgorithm("A128CBC-HS256", sigAlg)
alg.generateKey()
}
@Test
void testGenerateKeyWithLongerThanExpectedSigAlgKey() {
final byte[] macKeyBytes = new byte[64] // more than required 32 bytes / 256 bits
Randoms.secureRandom().nextBytes(macKeyBytes)
def sigAlg = new MacSignatureAlgorithm('HS256', 'HmacSHA256', 256) {
@Override
SecretKey generateKey() {
return new SecretKeySpec(macKeyBytes, 'HmacSHA256')
}
}
def alg = new HmacAesAeadAlgorithm("A128CBC-HS256", sigAlg)
def key = alg.generateKey()
def encryptionKeyBytes = key.getEncoded()
assertEquals 512, encryptionKeyBytes.length * Byte.SIZE
//per https://tools.ietf.org/html/rfc7518#section-5.2.2.1 ensure the first half of the generated encryption
// key is the first 32 bytes of the larger-than-expected mac key
byte[] macKeyFirst32Bytes = new byte[32]
byte[] encKeyFirst32Bytes = new byte[32]
System.arraycopy(macKeyBytes, 0, macKeyFirst32Bytes, 0, 32)
System.arraycopy(encryptionKeyBytes, 0, encKeyFirst32Bytes, 0, 32)
assert Arrays.equals(macKeyFirst32Bytes, encKeyFirst32Bytes)
}
}

View File

@ -7,8 +7,6 @@ import io.jsonwebtoken.security.Keys
import org.junit.Ignore
import org.junit.Test
import java.nio.charset.StandardCharsets
class Pbes2HsAkwAlgorithmTest {
@Ignore // for manual/developer testing only. Takes a long time and there is no deterministic output to assert
@ -25,9 +23,9 @@ class Pbes2HsAkwAlgorithmTest {
int skip = 6
//double scale = 0.5035246727
def payload = 'hello world'.getBytes(StandardCharsets.UTF_8)
def key = Keys.forPbe().setPassword('hellowor').setWorkFactor(iterations).build()
def req = new DefaultKeyRequest(null, null, null, key, new DefaultJweHeader(), EncryptionAlgorithms.A128GCM)
def password = 'hellowor'.toCharArray()
def key = Keys.forPbe().setPassword(password).setIterations(iterations).build()
def req = new DefaultKeyRequest(null, null, key, new DefaultJweHeader(), EncryptionAlgorithms.A128GCM)
int sum = 0;
for(int i = 0; i < tries; i++) {
long start = System.currentTimeMillis()

View File

@ -102,7 +102,7 @@ class RFC7516AppendixA3Test {
// https://datatracker.ietf.org/doc/html/rfc7516#appendix-A.3.8 :
//ensure that the algorithm reflects the test harness values:
SymmetricAeadAlgorithm enc = new HmacAesAeadAlgorithm(128) {
AeadAlgorithm enc = new HmacAesAeadAlgorithm(128) {
@Override
protected byte[] ensureInitializationVector(SecurityRequest request) {
return IV;

View File

@ -304,7 +304,7 @@ class RFC7517AppendixCTest {
}
}
PbeKey pbeKey = Keys.forPbe().setPassword(RFC_SHARED_PASSPHRASE).setWorkFactor(RFC_P2C).build()
PbeKey pbeKey = Keys.forPbe().setPassword(RFC_SHARED_PASSPHRASE.toCharArray()).setIterations(RFC_P2C).build()
String compact = Jwts.jweBuilder()
.setPayload(RFC_JWK_JSON)

View File

@ -70,7 +70,7 @@ class RFC7518AppendixB1Test {
void test() {
def alg = EncryptionAlgorithms.A128CBC_HS256
def request = new DefaultSymmetricAeadRequest(null, null, P, KEY, A, IV)
def request = new DefaultAeadRequest(null, null, P, KEY, A, IV)
def result = alg.encrypt(request);
byte[] ciphertext = result.getPayload()

View File

@ -1,8 +1,8 @@
package io.jsonwebtoken.impl.security
import io.jsonwebtoken.security.AeadRequest
import io.jsonwebtoken.security.AeadResult
import io.jsonwebtoken.security.EncryptionAlgorithms
import io.jsonwebtoken.security.SymmetricAeadRequest
import org.junit.Test
import javax.crypto.SecretKey
@ -70,7 +70,7 @@ class RFC7518AppendixB2Test {
void test() {
def alg = EncryptionAlgorithms.A192CBC_HS384
SymmetricAeadRequest req = new DefaultSymmetricAeadRequest(null, null, P, KEY, A, IV)
AeadRequest req = new DefaultAeadRequest(null, null, P, KEY, A, IV)
AeadResult result = alg.encrypt(req)
byte[] resultCiphertext = result.getPayload()

View File

@ -1,8 +1,8 @@
package io.jsonwebtoken.impl.security
import io.jsonwebtoken.security.AeadRequest
import io.jsonwebtoken.security.AeadResult
import io.jsonwebtoken.security.EncryptionAlgorithms
import io.jsonwebtoken.security.SymmetricAeadRequest
import org.junit.Test
import javax.crypto.SecretKey
@ -70,7 +70,7 @@ class RFC7518AppendixB3Test {
void test() {
def alg = EncryptionAlgorithms.A256CBC_HS512
SymmetricAeadRequest req = new DefaultSymmetricAeadRequest(null, null, P, KEY, A, IV)
AeadRequest req = new DefaultAeadRequest(null, null, P, KEY, A, IV)
AeadResult result = alg.encrypt(req)
byte[] resultCiphertext = result.getPayload()

View File

@ -1,7 +1,7 @@
package io.jsonwebtoken.security
import io.jsonwebtoken.impl.security.DefaultAeadRequest
import io.jsonwebtoken.impl.security.DefaultAeadResult
import io.jsonwebtoken.impl.security.DefaultSymmetricAeadRequest
import io.jsonwebtoken.impl.security.GcmAesAeadAlgorithm
import org.junit.Test
@ -41,11 +41,11 @@ class EncryptionAlgorithmsTest {
@Test
void testWithoutAad() {
for (SymmetricAeadAlgorithm alg : EncryptionAlgorithms.values()) {
for (AeadAlgorithm alg : EncryptionAlgorithms.values()) {
def key = alg.generateKey()
def request = new DefaultSymmetricAeadRequest(PLAINTEXT_BYTES, key, null)
def request = new DefaultAeadRequest(PLAINTEXT_BYTES, key, null)
def result = alg.encrypt(request)
@ -71,11 +71,11 @@ class EncryptionAlgorithmsTest {
@Test
void testWithAad() {
for (SymmetricAeadAlgorithm alg : EncryptionAlgorithms.values()) {
for (AeadAlgorithm alg : EncryptionAlgorithms.values()) {
def key = alg.generateKey()
def req = new DefaultSymmetricAeadRequest(null, null, PLAINTEXT_BYTES, key, AAD_BYTES)
def req = new DefaultAeadRequest(null, null, PLAINTEXT_BYTES, key, AAD_BYTES)
def result = alg.encrypt(req)