From d52289bd7a27acae736a44737ff636ab21a2d2ca Mon Sep 17 00:00:00 2001 From: Rob Winch <362503+rwinch@users.noreply.github.com> Date: Wed, 7 May 2025 10:54:55 -0500 Subject: [PATCH] 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) --- .../BouncyCastleAesCbcBytesEncryptor.java | 26 ++------ .../BouncyCastleAesGcmBytesEncryptor.java | 23 +------ ...stleAesBytesEncryptorEquivalencyTests.java | 60 ------------------- 3 files changed, 6 insertions(+), 103 deletions(-) diff --git a/crypto/src/main/java/org/springframework/security/crypto/encrypt/BouncyCastleAesCbcBytesEncryptor.java b/crypto/src/main/java/org/springframework/security/crypto/encrypt/BouncyCastleAesCbcBytesEncryptor.java index 362f28c255..565ec4d3c1 100644 --- a/crypto/src/main/java/org/springframework/security/crypto/encrypt/BouncyCastleAesCbcBytesEncryptor.java +++ b/crypto/src/main/java/org/springframework/security/crypto/encrypt/BouncyCastleAesCbcBytesEncryptor.java @@ -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 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; - } - } diff --git a/crypto/src/main/java/org/springframework/security/crypto/encrypt/BouncyCastleAesGcmBytesEncryptor.java b/crypto/src/main/java/org/springframework/security/crypto/encrypt/BouncyCastleAesGcmBytesEncryptor.java index 52d6e6cc48..15eb61ad70 100644 --- a/crypto/src/main/java/org/springframework/security/crypto/encrypt/BouncyCastleAesGcmBytesEncryptor.java +++ b/crypto/src/main/java/org/springframework/security/crypto/encrypt/BouncyCastleAesGcmBytesEncryptor.java @@ -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 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; - } - } diff --git a/crypto/src/test/java/org/springframework/security/crypto/encrypt/BouncyCastleAesBytesEncryptorEquivalencyTests.java b/crypto/src/test/java/org/springframework/security/crypto/encrypt/BouncyCastleAesBytesEncryptorEquivalencyTests.java index 0dda6ebfc5..7db08b3378 100644 --- a/crypto/src/test/java/org/springframework/security/crypto/encrypt/BouncyCastleAesBytesEncryptorEquivalencyTests.java +++ b/crypto/src/test/java/org/springframework/security/crypto/encrypt/BouncyCastleAesBytesEncryptorEquivalencyTests.java @@ -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];