spring-projects/spring-security · error · IllegalArgumentException
ivGenerator key length != block size 16
Error message
ivGenerator key length != block size 16
What it means
BouncyCastleAesBytesEncryptor uses a per-message IV equal in length to the AES block size (16 bytes). The constructor validates that the supplied ivGenerator produces exactly 16-byte keys and throws IllegalArgumentException otherwise, since any other IV length breaks CBC/GCM block processing.
Source
Thrown at crypto/src/main/java/org/springframework/security/crypto/encrypt/BouncyCastleAesBytesEncryptor.java:45
/**
* Base class for AES-256 encryption using Bouncy Castle.
*
* @author William Tran
*
*/
abstract class BouncyCastleAesBytesEncryptor implements BytesEncryptor {
final KeyParameter secretKey;
final BytesKeyGenerator ivGenerator;
BouncyCastleAesBytesEncryptor(String password, CharSequence salt) {
this(password, salt, KeyGenerators.secureRandom(16));
}
BouncyCastleAesBytesEncryptor(String password, CharSequence salt, BytesKeyGenerator ivGenerator) {
if (ivGenerator.getKeyLength() != 16) {
throw new IllegalArgumentException("ivGenerator key length != block size 16");
}
this.ivGenerator = ivGenerator;
PBEParametersGenerator keyGenerator = new PKCS5S2ParametersGenerator();
byte[] pkcs12PasswordBytes = PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(password.toCharArray());
keyGenerator.init(pkcs12PasswordBytes, Hex.decode(salt), 1024);
this.secretKey = (KeyParameter) keyGenerator.generateDerivedParameters(256);
}
}
View on GitHub (pinned to 96852e8860)
Solutions
- Pass KeyGenerators.secureRandom(16) as the ivGenerator.
- Verify the generator's getKeyLength() equals 16 before constructing.
- Use the two-arg constructor BouncyCastleAesBytesEncryptor(password, salt), which defaults to a correct 16-byte secure random generator.
Example fix
// before BytesKeyGenerator ivGen = KeyGenerators.secureRandom(32); BytesEncryptor e = new BouncyCastleAesBytesEncryptor(password, salt, ivGen); // throws // after BytesEncryptor e = new BouncyCastleAesBytesEncryptor(password, salt, KeyGenerators.secureRandom(16));
Defensive patterns
Strategy: validation
Validate before calling
if (ivGenerator.getKeyLength() != 16) throw new IllegalStateException("ivGenerator must produce 16-byte IVs"); Try / catch
try { encryptor = new BouncyCastleAesBytesEncryptor(password, salt, ivGen); } catch (IllegalArgumentException e) { encryptor = new BouncyCastleAesBytesEncryptor(password, salt); } Prevention
- Always construct IV generators with KeyGenerators.secureRandom(16).
- Never reuse a generator instance configured for a different block size across encryptors.
- Use the two-argument constructor unless you have a specific reason to supply your own IV generator.
When it happens
Trigger: new BouncyCastleAesBytesEncryptor(password, salt, ivGenerator) where ivGenerator.getKeyLength() != 16, e.g. KeyGenerators.secureRandom(8), a 32-byte generator, or a custom generator with shared(16)-style fixed but wrong-length keys.
Common situations: Reusing an IV generator configured for a different cipher (e.g. 8-byte for DES); misreading 'key length' docs and passing a generator sized for the AES key (32) rather than the block; refactors that share one generator constant across encryptors.
Related errors
- Bad strength
- unable to encrypt/decrypt
- Saml2Exception wrapping DecryptionException during encrypted
- Access is denied
- RunAsImplAuthenticationProvider.incorrectKey
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/b4091f63250b27a2.
Report an issue: GitHub.