Remove Unnecessary Backwards Compatability

Since this is going to be merged into Spring Security 7 (a major release) and AESFastEngine is deprecated,
we should no longer support it (as it will likely be removed from Bouncy Castle)
This commit is contained in:
Rob Winch 2025-05-07 10:54:55 -05:00
parent 5eb232cd3d
commit d52289bd7a
3 changed files with 6 additions and 103 deletions

View File

@ -16,12 +16,9 @@
package org.springframework.security.crypto.encrypt;
import java.util.function.Supplier;
import org.bouncycastle.crypto.BufferedBlockCipher;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.engines.AESEngine;
import org.bouncycastle.crypto.engines.AESFastEngine;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.modes.CBCModeCipher;
import org.bouncycastle.crypto.paddings.PKCS7Padding;
@ -41,8 +38,6 @@ import org.springframework.security.crypto.util.EncodingUtils;
*/
public class BouncyCastleAesCbcBytesEncryptor extends BouncyCastleAesBytesEncryptor {
private Supplier<CBCModeCipher> cipherFactory = () -> CBCBlockCipher.newInstance(AESEngine.newInstance());
public BouncyCastleAesCbcBytesEncryptor(String password, CharSequence salt) {
super(password, salt);
}
@ -54,8 +49,8 @@ public class BouncyCastleAesCbcBytesEncryptor extends BouncyCastleAesBytesEncryp
@Override
public byte[] encrypt(byte[] bytes) {
byte[] iv = this.ivGenerator.generateKey();
PaddedBufferedBlockCipher blockCipher = new PaddedBufferedBlockCipher(this.cipherFactory.get(),
new PKCS7Padding());
CBCModeCipher cbcModeCipher = CBCBlockCipher.newInstance(AESEngine.newInstance());
PaddedBufferedBlockCipher blockCipher = new PaddedBufferedBlockCipher(cbcModeCipher, new PKCS7Padding());
blockCipher.init(true, new ParametersWithIV(this.secretKey, iv));
byte[] encrypted = process(blockCipher, bytes);
return (iv != null) ? EncodingUtils.concatenate(iv, encrypted) : encrypted;
@ -63,10 +58,10 @@ public class BouncyCastleAesCbcBytesEncryptor extends BouncyCastleAesBytesEncryp
@Override
public byte[] decrypt(byte[] encryptedBytes) {
CBCModeCipher cbcModeCipher = CBCBlockCipher.newInstance(AESEngine.newInstance());
byte[] iv = EncodingUtils.subArray(encryptedBytes, 0, this.ivGenerator.getKeyLength());
encryptedBytes = EncodingUtils.subArray(encryptedBytes, this.ivGenerator.getKeyLength(), encryptedBytes.length);
PaddedBufferedBlockCipher blockCipher = new PaddedBufferedBlockCipher(this.cipherFactory.get(),
new PKCS7Padding());
PaddedBufferedBlockCipher blockCipher = new PaddedBufferedBlockCipher(cbcModeCipher, new PKCS7Padding());
blockCipher.init(false, new ParametersWithIV(this.secretKey, iv));
return process(blockCipher, encryptedBytes);
}
@ -88,17 +83,4 @@ public class BouncyCastleAesCbcBytesEncryptor extends BouncyCastleAesBytesEncryp
return out;
}
/**
* Used to test compatibility with deprecated {@link AESFastEngine}.
*/
@SuppressWarnings("deprecation")
static BouncyCastleAesCbcBytesEncryptor withAESFastEngine(String password, CharSequence salt,
BytesKeyGenerator ivGenerator) {
BouncyCastleAesCbcBytesEncryptor bytesEncryptor = new BouncyCastleAesCbcBytesEncryptor(password, salt,
ivGenerator);
bytesEncryptor.cipherFactory = () -> new CBCBlockCipher(new AESFastEngine());
return bytesEncryptor;
}
}

View File

@ -16,11 +16,8 @@
package org.springframework.security.crypto.encrypt;
import java.util.function.Supplier;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.engines.AESEngine;
import org.bouncycastle.crypto.engines.AESFastEngine;
import org.bouncycastle.crypto.modes.AEADBlockCipher;
import org.bouncycastle.crypto.modes.GCMBlockCipher;
import org.bouncycastle.crypto.params.AEADParameters;
@ -39,9 +36,6 @@ import org.springframework.security.crypto.util.EncodingUtils;
*/
public class BouncyCastleAesGcmBytesEncryptor extends BouncyCastleAesBytesEncryptor {
private Supplier<GCMBlockCipher> cipherFactory = () -> (GCMBlockCipher) GCMBlockCipher
.newInstance(AESEngine.newInstance());
public BouncyCastleAesGcmBytesEncryptor(String password, CharSequence salt) {
super(password, salt);
}
@ -53,7 +47,7 @@ public class BouncyCastleAesGcmBytesEncryptor extends BouncyCastleAesBytesEncryp
@Override
public byte[] encrypt(byte[] bytes) {
byte[] iv = this.ivGenerator.generateKey();
AEADBlockCipher blockCipher = this.cipherFactory.get();
AEADBlockCipher blockCipher = GCMBlockCipher.newInstance(AESEngine.newInstance());
blockCipher.init(true, new AEADParameters(this.secretKey, 128, iv, null));
byte[] encrypted = process(blockCipher, bytes);
return (iv != null) ? EncodingUtils.concatenate(iv, encrypted) : encrypted;
@ -63,7 +57,7 @@ public class BouncyCastleAesGcmBytesEncryptor extends BouncyCastleAesBytesEncryp
public byte[] decrypt(byte[] encryptedBytes) {
byte[] iv = EncodingUtils.subArray(encryptedBytes, 0, this.ivGenerator.getKeyLength());
encryptedBytes = EncodingUtils.subArray(encryptedBytes, this.ivGenerator.getKeyLength(), encryptedBytes.length);
AEADBlockCipher blockCipher = this.cipherFactory.get();
AEADBlockCipher blockCipher = GCMBlockCipher.newInstance(AESEngine.newInstance());
blockCipher.init(false, new AEADParameters(this.secretKey, 128, iv, null));
return process(blockCipher, encryptedBytes);
}
@ -85,17 +79,4 @@ public class BouncyCastleAesGcmBytesEncryptor extends BouncyCastleAesBytesEncryp
return out;
}
/**
* Used to test compatibility with deprecated {@link AESFastEngine}.
*/
@SuppressWarnings("deprecation")
static BouncyCastleAesGcmBytesEncryptor withAESFastEngine(String password, CharSequence salt,
BytesKeyGenerator ivGenerator) {
BouncyCastleAesGcmBytesEncryptor bytesEncryptor = new BouncyCastleAesGcmBytesEncryptor(password, salt,
ivGenerator);
bytesEncryptor.cipherFactory = () -> new GCMBlockCipher(new AESFastEngine());
return bytesEncryptor;
}
}

View File

@ -23,8 +23,6 @@ import java.util.Random;
import java.util.UUID;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.Test;
import org.springframework.security.crypto.codec.Hex;
@ -93,64 +91,6 @@ public class BouncyCastleAesBytesEncryptorEquivalencyTests {
testCompatibility(bcEncryptor, jceEncryptor);
}
@Test
public void bouncyCastleAesGcmWithAESFastEngineCompatible() throws Exception {
CryptoAssumptions.assumeGCMJCE();
BytesEncryptor fastEngineEncryptor = BouncyCastleAesGcmBytesEncryptor.withAESFastEngine(this.password,
this.salt, KeyGenerators.secureRandom(16));
BytesEncryptor defaultEngineEncryptor = new BouncyCastleAesGcmBytesEncryptor(this.password, this.salt,
KeyGenerators.secureRandom(16));
testCompatibility(fastEngineEncryptor, defaultEngineEncryptor);
}
@Test
public void bouncyCastleAesCbcWithAESFastEngineCompatible() throws Exception {
CryptoAssumptions.assumeCBCJCE();
BytesEncryptor fastEngineEncryptor = BouncyCastleAesCbcBytesEncryptor.withAESFastEngine(this.password,
this.salt, KeyGenerators.secureRandom(16));
BytesEncryptor defaultEngineEncryptor = new BouncyCastleAesCbcBytesEncryptor(this.password, this.salt,
KeyGenerators.secureRandom(16));
testCompatibility(fastEngineEncryptor, defaultEngineEncryptor);
}
/**
* Comment out @Disabled below to compare relative speed of deprecated AESFastEngine
* with the default AESEngine.
*/
@Disabled
@RepeatedTest(100)
public void bouncyCastleAesGcmWithAESFastEngineSpeedTest() throws Exception {
CryptoAssumptions.assumeGCMJCE();
BytesEncryptor defaultEngineEncryptor = new BouncyCastleAesGcmBytesEncryptor(this.password, this.salt,
KeyGenerators.secureRandom(16));
BytesEncryptor fastEngineEncryptor = BouncyCastleAesGcmBytesEncryptor.withAESFastEngine(this.password,
this.salt, KeyGenerators.secureRandom(16));
long defaultNanos = testSpeed(defaultEngineEncryptor);
long fastNanos = testSpeed(fastEngineEncryptor);
System.out.println(nanosToReadableString("AES GCM w/Default Engine", defaultNanos));
System.out.println(nanosToReadableString("AES GCM w/ Fast Engine", fastNanos));
assertThat(fastNanos).isLessThan(defaultNanos);
}
/**
* Comment out @Disabled below to compare relative speed of deprecated AESFastEngine
* with the default AESEngine.
*/
@Disabled
@RepeatedTest(100)
public void bouncyCastleAesCbcWithAESFastEngineSpeedTest() throws Exception {
CryptoAssumptions.assumeCBCJCE();
BytesEncryptor defaultEngineEncryptor = new BouncyCastleAesCbcBytesEncryptor(this.password, this.salt,
KeyGenerators.secureRandom(16));
BytesEncryptor fastEngineEncryptor = BouncyCastleAesCbcBytesEncryptor.withAESFastEngine(this.password,
this.salt, KeyGenerators.secureRandom(16));
long defaultNanos = testSpeed(defaultEngineEncryptor);
long fastNanos = testSpeed(fastEngineEncryptor);
System.out.println(nanosToReadableString("AES CBC w/Default Engine", defaultNanos));
System.out.println(nanosToReadableString("AES CBC w/ Fast Engine", fastNanos));
assertThat(fastNanos).isLessThan(defaultNanos);
}
private void testEquivalence(BytesEncryptor left, BytesEncryptor right) {
for (int size = 1; size < 2048; size++) {
this.testData = new byte[size];