AESGCM class uses hardcoded SecureRandom in key encryption
Issue #324
invalid
Problem
I tried to set a custom SecureRandom
within RCAEncrypter
's JCAContext
and it is not getting used by the part of the algorithm that generates the encrypted key. I detected the issue by using a mock SecureRandom
.
Description
The AESGCM class initializes ciphers during encryption and decryption with an hardcoded SecureRandom
. Relevant snippet contains the definition of the AESGCM.encrypt()
method:
public static AuthenticatedCipherText encrypt(final SecretKey secretKey,
final Container<byte[]> ivContainer,
final byte[] plainText,
final byte[] authData,
final Provider provider)
throws JOSEException {
// Key alg must be "AES"
final SecretKey aesKey = KeyUtils.toAESKey(secretKey);
Cipher cipher;
byte[] iv = ivContainer.get();
try {
if (provider != null) {
cipher = Cipher.getInstance("AES/GCM/NoPadding", provider);
} else {
cipher = Cipher.getInstance("AES/GCM/NoPadding");
}
GCMParameterSpec gcmSpec = new GCMParameterSpec(AUTH_TAG_BIT_LENGTH, iv);
// this initialization uses hardcoded JceSecurity.RANDOM !!!
cipher.init(Cipher.ENCRYPT_MODE, aesKey, gcmSpec);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException e) {
throw new JOSEException("Couldn't create AES/GCM/NoPadding cipher: " + e.getMessage(), e);
} catch (NoClassDefFoundError e) {
// We have Java 6, GCMParameterSpec not available,
// switch to BouncyCastle API
return LegacyAESGCM.encrypt(aesKey, iv, plainText, authData);
}
cipher.updateAAD(authData);
byte[] cipherOutput;
try {
cipherOutput = cipher.doFinal(plainText);
} catch (IllegalBlockSizeException | BadPaddingException e) {
throw new JOSEException("Couldn't encrypt with AES/GCM/NoPadding: " + e.getMessage(), e);
}
final int tagPos = cipherOutput.length - ByteUtils.byteLength(AUTH_TAG_BIT_LENGTH);
byte[] cipherText = ByteUtils.subArray(cipherOutput, 0, tagPos);
byte[] authTag = ByteUtils.subArray(cipherOutput, tagPos, ByteUtils.byteLength(AUTH_TAG_BIT_LENGTH));
// retrieve the actual IV used by the cipher -- it may be internally-generated.
ivContainer.set(actualIVOf(cipher));
return new AuthenticatedCipherText(cipherText, authTag);
}
Given that the JCAContext
does allow usage of a custom implementation SecureRandom
via its setSecureRandom()
method, shouldn't this class make use of the custom SecureRandom
as well?
Comments (2)
-
-
- changed status to invalid
- Log in to comment
The IV is generated from the JCA context, prior to calling the cited method:
https://bitbucket.org/connect2id/nimbus-jose-jwt/src/dd19a712b2b8c0f7c64cb6678cbf96f97d81553e/src/main/java/com/nimbusds/jose/crypto/impl/ContentCryptoProvider.java#lines-190
Or perhaps you meant something else?