This is an automated email from the ASF dual-hosted git repository.

pvillard pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git


The following commit(s) were added to refs/heads/main by this push:
     new a7ba5bb  NIFI-8319 Added AES/CBC/NoPadding for decryption in 
EncryptContent Processor
a7ba5bb is described below

commit a7ba5bb4f8cb4af9bf9e0db176202365570b7e28
Author: exceptionfactory <[email protected]>
AuthorDate: Fri Mar 12 16:00:42 2021 -0600

    NIFI-8319 Added AES/CBC/NoPadding for decryption in EncryptContent Processor
    
    Signed-off-by: Pierre Villard <[email protected]>
    
    This closes #4894.
---
 .../nifi/security/util/EncryptionMethod.java       |  3 +-
 .../crypto/AESKeyedCipherProviderGroovyTest.groovy | 28 ++++++-------
 .../crypto/Argon2CipherProviderGroovyTest.groovy   | 28 +++++--------
 .../crypto/BcryptCipherProviderGroovyTest.groovy   | 46 +++++++---------------
 .../util/crypto/CipherUtilityGroovyTest.groovy     |  5 ++-
 .../crypto/PBKDF2CipherProviderGroovyTest.groovy   | 38 ++++++------------
 .../crypto/ScryptCipherProviderGroovyTest.groovy   | 33 ++++++----------
 .../nifi/processors/standard/EncryptContent.java   | 17 ++++++--
 .../standard/TestEncryptContentGroovy.groovy       | 43 +++++++++++++++-----
 9 files changed, 113 insertions(+), 128 deletions(-)

diff --git 
a/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/EncryptionMethod.java
 
b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/EncryptionMethod.java
index 62d72a2..0ba3d59 100644
--- 
a/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/EncryptionMethod.java
+++ 
b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/EncryptionMethod.java
@@ -49,7 +49,8 @@ public enum EncryptionMethod {
     SHA_TWOFISH("PBEWITHSHAANDTWOFISH-CBC", "BC", false, false),
     PGP("PGP", "BC", false, false),
     PGP_ASCII_ARMOR("PGP-ASCII-ARMOR", "BC", false, false),
-    // New encryption methods which used keyed encryption
+    // AES/CBC/NoPadding supported for decryption
+    AES_CBC_NO_PADDING("AES/CBC/NoPadding", "BC", false, true),
     AES_CBC("AES/CBC/PKCS7Padding", "BC", false, true),
     AES_CTR("AES/CTR/NoPadding", "BC", false, true),
     AES_GCM("AES/GCM/NoPadding", "BC", false, true);
diff --git 
a/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/AESKeyedCipherProviderGroovyTest.groovy
 
b/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/AESKeyedCipherProviderGroovyTest.groovy
index 8082149..35d1464 100644
--- 
a/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/AESKeyedCipherProviderGroovyTest.groovy
+++ 
b/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/AESKeyedCipherProviderGroovyTest.groovy
@@ -43,6 +43,8 @@ class AESKeyedCipherProviderGroovyTest {
 
     private static final String KEY_HEX = "0123456789ABCDEFFEDCBA9876543210"
 
+    private static final String PLAINTEXT = "ExactBlockSizeRequiredForProcess"
+
     private static final List<EncryptionMethod> keyedEncryptionMethods = 
EncryptionMethod.values().findAll { it.keyedCipher }
 
     private static final SecretKey key = new 
SecretKeySpec(Hex.decodeHex(KEY_HEX as char[]), "AES")
@@ -73,8 +75,6 @@ class AESKeyedCipherProviderGroovyTest {
         // Arrange
         KeyedCipherProvider cipherProvider = new AESKeyedCipherProvider()
 
-        final String plaintext = "This is a plaintext message."
-
         // Act
         for (EncryptionMethod em : keyedEncryptionMethods) {
             logger.info("Using algorithm: ${em.getAlgorithm()}")
@@ -84,7 +84,7 @@ class AESKeyedCipherProviderGroovyTest {
             byte[] iv = cipher.getIV()
             logger.info("IV: ${Hex.encodeHexString(iv)}")
 
-            byte[] cipherBytes = cipher.doFinal(plaintext.getBytes("UTF-8"))
+            byte[] cipherBytes = cipher.doFinal(PLAINTEXT.getBytes("UTF-8"))
             logger.info("Cipher text: ${Hex.encodeHexString(cipherBytes)} 
${cipherBytes.length}")
 
             cipher = cipherProvider.getCipher(em, key, iv, false)
@@ -93,7 +93,7 @@ class AESKeyedCipherProviderGroovyTest {
             logger.info("Recovered: ${recovered}")
 
             // Assert
-            assert plaintext.equals(recovered)
+            assert PLAINTEXT.equals(recovered)
         }
     }
 
@@ -102,8 +102,6 @@ class AESKeyedCipherProviderGroovyTest {
         // Arrange
         KeyedCipherProvider cipherProvider = new AESKeyedCipherProvider()
 
-        final String plaintext = "This is a plaintext message."
-
         // Act
         keyedEncryptionMethods.each { EncryptionMethod em ->
             logger.info("Using algorithm: ${em.getAlgorithm()}")
@@ -113,7 +111,7 @@ class AESKeyedCipherProviderGroovyTest {
             // Initialize a cipher for encryption
             Cipher cipher = cipherProvider.getCipher(em, key, iv, true)
 
-            byte[] cipherBytes = cipher.doFinal(plaintext.getBytes("UTF-8"))
+            byte[] cipherBytes = cipher.doFinal(PLAINTEXT.getBytes("UTF-8"))
             logger.info("Cipher text: ${Hex.encodeHexString(cipherBytes)} 
${cipherBytes.length}")
 
             cipher = cipherProvider.getCipher(em, key, iv, false)
@@ -122,7 +120,7 @@ class AESKeyedCipherProviderGroovyTest {
             logger.info("Recovered: ${recovered}")
 
             // Assert
-            assert plaintext.equals(recovered)
+            assert PLAINTEXT.equals(recovered)
         }
     }
 
@@ -134,8 +132,6 @@ class AESKeyedCipherProviderGroovyTest {
         KeyedCipherProvider cipherProvider = new AESKeyedCipherProvider()
         final List<Integer> LONG_KEY_LENGTHS = [192, 256]
 
-        final String plaintext = "This is a plaintext message."
-
         SecureRandom secureRandom = new SecureRandom()
 
         // Act
@@ -156,7 +152,7 @@ class AESKeyedCipherProviderGroovyTest {
                 // Initialize a cipher for encryption
                 Cipher cipher = cipherProvider.getCipher(em, localKey, iv, 
true)
 
-                byte[] cipherBytes = 
cipher.doFinal(plaintext.getBytes("UTF-8"))
+                byte[] cipherBytes = 
cipher.doFinal(PLAINTEXT.getBytes("UTF-8"))
                 logger.info("Cipher text: ${Hex.encodeHexString(cipherBytes)} 
${cipherBytes.length}")
 
                 cipher = cipherProvider.getCipher(em, localKey, iv, false)
@@ -165,7 +161,7 @@ class AESKeyedCipherProviderGroovyTest {
                 logger.info("Recovered: ${recovered}")
 
                 // Assert
-                assert plaintext.equals(recovered)
+                assert PLAINTEXT.equals(recovered)
             }
         }
     }
@@ -240,7 +236,7 @@ class AESKeyedCipherProviderGroovyTest {
         // Arrange
         KeyedCipherProvider cipherProvider = new AESKeyedCipherProvider()
 
-        final String PLAINTEXT = "This is a plaintext message."
+        final String plaintext = "This is a plaintext message."
 
         // These values can be generated by running `$ ./openssl_aes.rb` in 
the terminal
         final byte[] IV = Hex.decodeHex("e0bc8cc7fbc0bdfdc184dc22ce2fcb5b" as 
char[])
@@ -261,7 +257,7 @@ class AESKeyedCipherProviderGroovyTest {
         logger.info("Recovered: ${recovered}")
 
         // Assert
-        assert PLAINTEXT.equals(recovered)
+        assert plaintext.equals(recovered)
     }
 
     @Test
@@ -269,8 +265,6 @@ class AESKeyedCipherProviderGroovyTest {
         // Arrange
         KeyedCipherProvider cipherProvider = new AESKeyedCipherProvider()
 
-        final String plaintext = "This is a plaintext message."
-
         // Act
         keyedEncryptionMethods.each { EncryptionMethod em ->
             logger.info("Using algorithm: ${em.getAlgorithm()}")
@@ -280,7 +274,7 @@ class AESKeyedCipherProviderGroovyTest {
             // Initialize a cipher for encryption
             Cipher cipher = cipherProvider.getCipher(em, key, iv, true)
 
-            byte[] cipherBytes = cipher.doFinal(plaintext.getBytes("UTF-8"))
+            byte[] cipherBytes = cipher.doFinal(PLAINTEXT.getBytes("UTF-8"))
             logger.info("Cipher text: ${Hex.encodeHexString(cipherBytes)} 
${cipherBytes.length}")
 
             def msg = shouldFail(IllegalArgumentException) {
diff --git 
a/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/Argon2CipherProviderGroovyTest.groovy
 
b/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/Argon2CipherProviderGroovyTest.groovy
index dde7fcb..79c92d4 100644
--- 
a/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/Argon2CipherProviderGroovyTest.groovy
+++ 
b/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/Argon2CipherProviderGroovyTest.groovy
@@ -42,6 +42,8 @@ import static groovy.test.GroovyAssert.shouldFail
 class Argon2CipherProviderGroovyTest extends GroovyTestCase {
     private static final Logger logger = 
LoggerFactory.getLogger(Argon2CipherProviderGroovyTest.class)
 
+    private static final String PLAINTEXT = "ExactBlockSizeRequiredForProcess"
+
     private static List<EncryptionMethod> strongKDFEncryptionMethods
 
     private static final int DEFAULT_KEY_LENGTH = 128
@@ -85,8 +87,6 @@ class Argon2CipherProviderGroovyTest extends GroovyTestCase {
         final String PASSWORD = "shortPassword"
         final byte[] SALT = cipherProvider.generateSalt()
 
-        final String plaintext = "This is a plaintext message."
-
         // Act
         for (EncryptionMethod em : strongKDFEncryptionMethods) {
             logger.info("Using algorithm: ${em.getAlgorithm()}")
@@ -96,7 +96,7 @@ class Argon2CipherProviderGroovyTest extends GroovyTestCase {
             byte[] iv = cipher.getIV()
             logger.info("IV: ${Hex.encodeHexString(iv)}")
 
-            byte[] cipherBytes = cipher.doFinal(plaintext.getBytes("UTF-8"))
+            byte[] cipherBytes = cipher.doFinal(PLAINTEXT.getBytes("UTF-8"))
             logger.info("Cipher text: ${Hex.encodeHexString(cipherBytes)} 
${cipherBytes.length}")
 
             cipher = cipherProvider.getCipher(em, PASSWORD, SALT, iv, 
DEFAULT_KEY_LENGTH, false)
@@ -105,7 +105,7 @@ class Argon2CipherProviderGroovyTest extends GroovyTestCase 
{
             logger.info("Recovered: ${recovered}")
 
             // Assert
-            assert plaintext.equals(recovered)
+            assert PLAINTEXT.equals(recovered)
         }
     }
 
@@ -210,8 +210,6 @@ class Argon2CipherProviderGroovyTest extends GroovyTestCase 
{
         final byte[] SALT = cipherProvider.generateSalt()
         final byte[] IV = Hex.decodeHex("01" * 16 as char[])
 
-        final String plaintext = "This is a plaintext message."
-
         // Act
         for (EncryptionMethod em : strongKDFEncryptionMethods) {
             logger.info("Using algorithm: ${em.getAlgorithm()}")
@@ -220,7 +218,7 @@ class Argon2CipherProviderGroovyTest extends GroovyTestCase 
{
             Cipher cipher = cipherProvider.getCipher(em, PASSWORD, SALT, IV, 
DEFAULT_KEY_LENGTH, true)
             logger.info("IV: ${Hex.encodeHexString(IV)}")
 
-            byte[] cipherBytes = cipher.doFinal(plaintext.getBytes("UTF-8"))
+            byte[] cipherBytes = cipher.doFinal(PLAINTEXT.getBytes("UTF-8"))
             logger.info("Cipher text: ${Hex.encodeHexString(cipherBytes)} 
${cipherBytes.length}")
 
             cipher = cipherProvider.getCipher(em, PASSWORD, SALT, IV, 
DEFAULT_KEY_LENGTH, false)
@@ -229,7 +227,7 @@ class Argon2CipherProviderGroovyTest extends GroovyTestCase 
{
             logger.info("Recovered: ${recovered}")
 
             // Assert
-            assert plaintext.equals(recovered)
+            assert PLAINTEXT.equals(recovered)
         }
     }
 
@@ -244,8 +242,6 @@ class Argon2CipherProviderGroovyTest extends GroovyTestCase 
{
 
         final int LONG_KEY_LENGTH = 256
 
-        final String plaintext = "This is a plaintext message."
-
         // Act
         for (EncryptionMethod em : strongKDFEncryptionMethods) {
             logger.info("Using algorithm: ${em.getAlgorithm()}")
@@ -255,7 +251,7 @@ class Argon2CipherProviderGroovyTest extends GroovyTestCase 
{
             byte[] iv = cipher.getIV()
             logger.info("IV: ${Hex.encodeHexString(iv)}")
 
-            byte[] cipherBytes = cipher.doFinal(plaintext.getBytes("UTF-8"))
+            byte[] cipherBytes = cipher.doFinal(PLAINTEXT.getBytes("UTF-8"))
             logger.info("Cipher text: ${Hex.encodeHexString(cipherBytes)} 
${cipherBytes.length}")
 
             cipher = cipherProvider.getCipher(em, PASSWORD, SALT, iv, 
LONG_KEY_LENGTH, false)
@@ -264,7 +260,7 @@ class Argon2CipherProviderGroovyTest extends GroovyTestCase 
{
             logger.info("Recovered: ${recovered}")
 
             // Assert
-            assert plaintext.equals(recovered)
+            assert PLAINTEXT.equals(recovered)
         }
     }
 
@@ -369,8 +365,6 @@ class Argon2CipherProviderGroovyTest extends GroovyTestCase 
{
         final byte[] SALT = cipherProvider.generateSalt()
         final byte[] IV = Hex.decodeHex("00" * 16 as char[])
 
-        final String plaintext = "This is a plaintext message."
-
         // Act
         for (EncryptionMethod em : strongKDFEncryptionMethods) {
             logger.info("Using algorithm: ${em.getAlgorithm()}")
@@ -379,7 +373,7 @@ class Argon2CipherProviderGroovyTest extends GroovyTestCase 
{
             Cipher cipher = cipherProvider.getCipher(em, PASSWORD, SALT, IV, 
DEFAULT_KEY_LENGTH, true)
             logger.info("IV: ${Hex.encodeHexString(IV)}")
 
-            byte[] cipherBytes = cipher.doFinal(plaintext.getBytes("UTF-8"))
+            byte[] cipherBytes = cipher.doFinal(PLAINTEXT.getBytes("UTF-8"))
             logger.info("Cipher text: ${Hex.encodeHexString(cipherBytes)} 
${cipherBytes.length}")
 
             def msg = shouldFail(IllegalArgumentException) {
@@ -399,8 +393,6 @@ class Argon2CipherProviderGroovyTest extends GroovyTestCase 
{
         final byte[] SALT = cipherProvider.generateSalt()
         final byte[] IV = Hex.decodeHex("01" * 16 as char[])
 
-        final String PLAINTEXT = "This is a plaintext message."
-
         final def VALID_KEY_LENGTHS = AES_KEY_LENGTHS
         EncryptionMethod encryptionMethod = EncryptionMethod.AES_CBC
 
@@ -432,8 +424,6 @@ class Argon2CipherProviderGroovyTest extends GroovyTestCase 
{
         final byte[] SALT = cipherProvider.generateSalt()
         final byte[] IV = Hex.decodeHex("00" * 16 as char[])
 
-        final String PLAINTEXT = "This is a plaintext message."
-
         final def INVALID_KEY_LENGTHS = [-1, 40, 64, 112, 512]
         EncryptionMethod encryptionMethod = EncryptionMethod.AES_CBC
 
diff --git 
a/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/BcryptCipherProviderGroovyTest.groovy
 
b/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/BcryptCipherProviderGroovyTest.groovy
index b60c58c..4968d3b 100644
--- 
a/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/BcryptCipherProviderGroovyTest.groovy
+++ 
b/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/BcryptCipherProviderGroovyTest.groovy
@@ -46,6 +46,8 @@ import static org.junit.Assert.assertTrue
 class BcryptCipherProviderGroovyTest {
     private static final Logger logger = 
LoggerFactory.getLogger(BcryptCipherProviderGroovyTest.class)
 
+    private static final String PLAINTEXT = "ExactBlockSizeRequiredForProcess"
+
     private static List<EncryptionMethod> strongKDFEncryptionMethods
 
     private static final int DEFAULT_KEY_LENGTH = 128
@@ -86,8 +88,6 @@ class BcryptCipherProviderGroovyTest {
         final String PASSWORD = "shortPassword"
         final byte[] SALT = cipherProvider.generateSalt()
 
-        final String plaintext = "This is a plaintext message."
-
         // Act
         for (EncryptionMethod em : strongKDFEncryptionMethods) {
             logger.info("Using algorithm: ${em.getAlgorithm()}")
@@ -97,7 +97,7 @@ class BcryptCipherProviderGroovyTest {
             byte[] iv = cipher.getIV()
             logger.info("IV: ${Hex.encodeHexString(iv)}")
 
-            byte[] cipherBytes = cipher.doFinal(plaintext.getBytes("UTF-8"))
+            byte[] cipherBytes = cipher.doFinal(PLAINTEXT.getBytes("UTF-8"))
             logger.info("Cipher text: ${Hex.encodeHexString(cipherBytes)} 
${cipherBytes.length}")
 
             cipher = cipherProvider.getCipher(em, PASSWORD, SALT, iv, 
DEFAULT_KEY_LENGTH, false)
@@ -106,7 +106,7 @@ class BcryptCipherProviderGroovyTest {
             logger.info("Recovered: ${recovered}")
 
             // Assert
-            assert plaintext.equals(recovered)
+            assert PLAINTEXT.equals(recovered)
         }
     }
 
@@ -119,8 +119,6 @@ class BcryptCipherProviderGroovyTest {
         final byte[] SALT = cipherProvider.generateSalt()
         final byte[] IV = Hex.decodeHex("01" * 16 as char[])
 
-        final String plaintext = "This is a plaintext message."
-
         // Act
         for (EncryptionMethod em : strongKDFEncryptionMethods) {
             logger.info("Using algorithm: ${em.getAlgorithm()}")
@@ -129,7 +127,7 @@ class BcryptCipherProviderGroovyTest {
             Cipher cipher = cipherProvider.getCipher(em, PASSWORD, SALT, IV, 
DEFAULT_KEY_LENGTH, true)
             logger.info("IV: ${Hex.encodeHexString(IV)}")
 
-            byte[] cipherBytes = cipher.doFinal(plaintext.getBytes("UTF-8"))
+            byte[] cipherBytes = cipher.doFinal(PLAINTEXT.getBytes("UTF-8"))
             logger.info("Cipher text: ${Hex.encodeHexString(cipherBytes)} 
${cipherBytes.length}")
 
             cipher = cipherProvider.getCipher(em, PASSWORD, SALT, IV, 
DEFAULT_KEY_LENGTH, false)
@@ -138,7 +136,7 @@ class BcryptCipherProviderGroovyTest {
             logger.info("Recovered: ${recovered}")
 
             // Assert
-            assert plaintext.equals(recovered)
+            assert PLAINTEXT.equals(recovered)
         }
     }
 
@@ -155,8 +153,6 @@ class BcryptCipherProviderGroovyTest {
 
         final int LONG_KEY_LENGTH = 256
 
-        final String plaintext = "This is a plaintext message."
-
         // Act
         for (EncryptionMethod em : strongKDFEncryptionMethods) {
             logger.info("Using algorithm: ${em.getAlgorithm()}")
@@ -166,7 +162,7 @@ class BcryptCipherProviderGroovyTest {
             byte[] iv = cipher.getIV()
             logger.info("IV: ${Hex.encodeHexString(iv)}")
 
-            byte[] cipherBytes = cipher.doFinal(plaintext.getBytes("UTF-8"))
+            byte[] cipherBytes = cipher.doFinal(PLAINTEXT.getBytes("UTF-8"))
             logger.info("Cipher text: ${Hex.encodeHexString(cipherBytes)} 
${cipherBytes.length}")
 
             cipher = cipherProvider.getCipher(em, PASSWORD, SALT, iv, 
LONG_KEY_LENGTH, false)
@@ -175,7 +171,7 @@ class BcryptCipherProviderGroovyTest {
             logger.info("Recovered: ${recovered}")
 
             // Assert
-            assert plaintext.equals(recovered)
+            assert PLAINTEXT.equals(recovered)
         }
     }
 
@@ -389,8 +385,6 @@ class BcryptCipherProviderGroovyTest {
         final byte[] SALT = cipherProvider.generateSalt()
         final byte[] IV = Hex.decodeHex("00" * 16 as char[])
 
-        final String plaintext = "This is a plaintext message."
-
         // Act
         for (EncryptionMethod em : strongKDFEncryptionMethods) {
             logger.info("Using algorithm: ${em.getAlgorithm()}")
@@ -399,7 +393,7 @@ class BcryptCipherProviderGroovyTest {
             Cipher cipher = cipherProvider.getCipher(em, PASSWORD, SALT, IV, 
DEFAULT_KEY_LENGTH, true)
             logger.info("IV: ${Hex.encodeHexString(IV)}")
 
-            byte[] cipherBytes = cipher.doFinal(plaintext.getBytes("UTF-8"))
+            byte[] cipherBytes = cipher.doFinal(PLAINTEXT.getBytes("UTF-8"))
             logger.info("Cipher text: ${Hex.encodeHexString(cipherBytes)} 
${cipherBytes.length}")
 
             def msg = shouldFail(IllegalArgumentException) {
@@ -420,8 +414,6 @@ class BcryptCipherProviderGroovyTest {
         final byte[] SALT = cipherProvider.generateSalt()
         final byte[] IV = Hex.decodeHex("01" * 16 as char[])
 
-        final String PLAINTEXT = "This is a plaintext message."
-
         // Currently only AES ciphers are compatible with Bcrypt, so redundant 
to test all algorithms
         final def VALID_KEY_LENGTHS = AES_KEY_LENGTHS
         EncryptionMethod encryptionMethod = EncryptionMethod.AES_CBC
@@ -456,8 +448,6 @@ class BcryptCipherProviderGroovyTest {
         final byte[] SALT = cipherProvider.generateSalt()
         final byte[] IV = Hex.decodeHex("00" * 16 as char[])
 
-        final String PLAINTEXT = "This is a plaintext message."
-
         // Currently only AES ciphers are compatible with Bcrypt, so redundant 
to test all algorithms
         final def INVALID_KEY_LENGTHS = [-1, 40, 64, 112, 512]
         EncryptionMethod encryptionMethod = EncryptionMethod.AES_CBC
@@ -520,8 +510,6 @@ class BcryptCipherProviderGroovyTest {
         byte[] keyDigestBytes = sha512.digest(hashOutputBytes[-31..-1] as 
byte[])
         logger.info("Key digest (${keyDigestBytes.length}): 
${Hex.encodeHexString(keyDigestBytes)}")
 
-        final String plaintext = "This is a plaintext message."
-
         // Act
         for (EncryptionMethod em : strongKDFEncryptionMethods) {
             logger.info("Using algorithm: ${em.getAlgorithm()}")
@@ -531,7 +519,7 @@ class BcryptCipherProviderGroovyTest {
             byte[] iv = cipher.getIV()
             logger.info("IV: ${Hex.encodeHexString(iv)}")
 
-            byte[] cipherBytes = cipher.doFinal(plaintext.getBytes("UTF-8"))
+            byte[] cipherBytes = cipher.doFinal(PLAINTEXT.getBytes("UTF-8"))
             logger.info("Cipher text: ${Hex.encodeHexString(cipherBytes)} 
${cipherBytes.length}")
 
             cipher = cipherProvider.getCipher(em, PASSWORD, SALT, iv, 
DEFAULT_KEY_LENGTH, false)
@@ -551,8 +539,8 @@ class BcryptCipherProviderGroovyTest {
             logger.info("Verified: ${verificationRecovered}")
 
             // Assert
-            assert plaintext == recovered
-            assert plaintext == verificationRecovered
+            assert PLAINTEXT == recovered
+            assert PLAINTEXT == verificationRecovered
         }
     }
 
@@ -564,8 +552,6 @@ class BcryptCipherProviderGroovyTest {
         final String PASSWORD = "shortPassword"
         final byte[] SALT = cipherProvider.generateSalt()
 
-        final String plaintext = "This is a plaintext message."
-
         // Act
         for (EncryptionMethod em : strongKDFEncryptionMethods) {
             logger.info("Using algorithm: ${em.getAlgorithm()}")
@@ -575,7 +561,7 @@ class BcryptCipherProviderGroovyTest {
             byte[] iv = cipher.getIV()
             logger.info("IV: ${Hex.encodeHexString(iv)}")
 
-            byte[] cipherBytes = cipher.doFinal(plaintext.getBytes("UTF-8"))
+            byte[] cipherBytes = cipher.doFinal(PLAINTEXT.getBytes("UTF-8"))
             logger.info("Cipher text: ${Hex.encodeHexString(cipherBytes)} 
${cipherBytes.length}")
 
             cipher = cipherProvider.getLegacyDecryptCipher(em, PASSWORD, SALT, 
iv, DEFAULT_KEY_LENGTH)
@@ -584,7 +570,7 @@ class BcryptCipherProviderGroovyTest {
             logger.info("Recovered: ${recovered}")
 
             // Assert
-            assert plaintext == recovered
+            assert PLAINTEXT == recovered
         }
     }
 
@@ -597,8 +583,6 @@ class BcryptCipherProviderGroovyTest {
         final byte[] SALT = null
         final EncryptionMethod em = EncryptionMethod.AES_CBC
 
-        final String plaintext = "This is a plaintext message."
-
         // Act
         logger.info("Using algorithm: ${em.getAlgorithm()}")
 
@@ -610,7 +594,7 @@ class BcryptCipherProviderGroovyTest {
         }
         logger.expected("Encrypt error: ${encryptMsg}")
 
-        byte[] cipherBytes = 
plaintext.reverse().getBytes(StandardCharsets.UTF_8)
+        byte[] cipherBytes = 
PLAINTEXT.reverse().getBytes(StandardCharsets.UTF_8)
         logger.info("Cipher text: ${Hex.encodeHexString(cipherBytes)} 
${cipherBytes.length}")
 
         def decryptMsg = shouldFail(IllegalArgumentException) {
diff --git 
a/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/CipherUtilityGroovyTest.groovy
 
b/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/CipherUtilityGroovyTest.groovy
index 424b810..bb42a90 100644
--- 
a/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/CipherUtilityGroovyTest.groovy
+++ 
b/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/CipherUtilityGroovyTest.groovy
@@ -40,7 +40,7 @@ class CipherUtilityGroovyTest extends GroovyTestCase {
     private static final List<String> SYMMETRIC_ALGORITHMS = 
EncryptionMethod.values().findAll { it.algorithm.startsWith("PBE") || 
it.algorithm.startsWith("AES") }*.algorithm
     private static final Map<String, List<String>> ALGORITHMS_MAPPED_BY_CIPHER 
= SYMMETRIC_ALGORITHMS.groupBy { String algorithm -> CIPHERS.find { 
algorithm.contains(it) } }
 
-    // Manually mapped as of 01/19/16 0.5.0
+    // Manually mapped as of 03/21/21 1.13.0
     private static final Map<Integer, List<String>> 
ALGORITHMS_MAPPED_BY_KEY_LENGTH = [
             (40) : ["PBEWITHSHAAND40BITRC2-CBC",
                     "PBEWITHSHAAND40BITRC4"],
@@ -56,18 +56,21 @@ class CipherUtilityGroovyTest extends GroovyTestCase {
                     "PBEWITHSHAAND128BITRC2-CBC",
                     "PBEWITHSHAAND128BITRC4",
                     "PBEWITHSHAANDTWOFISH-CBC",
+                    "AES/CBC/NoPadding",
                     "AES/CBC/PKCS7Padding",
                     "AES/CTR/NoPadding",
                     "AES/GCM/NoPadding"],
             (192): ["PBEWITHMD5AND192BITAES-CBC-OPENSSL",
                     "PBEWITHSHA256AND192BITAES-CBC-BC",
                     "PBEWITHSHAAND192BITAES-CBC-BC",
+                    "AES/CBC/NoPadding",
                     "AES/CBC/PKCS7Padding",
                     "AES/CTR/NoPadding",
                     "AES/GCM/NoPadding"],
             (256): ["PBEWITHMD5AND256BITAES-CBC-OPENSSL",
                     "PBEWITHSHA256AND256BITAES-CBC-BC",
                     "PBEWITHSHAAND256BITAES-CBC-BC",
+                    "AES/CBC/NoPadding",
                     "AES/CBC/PKCS7Padding",
                     "AES/CTR/NoPadding",
                     "AES/GCM/NoPadding"]
diff --git 
a/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/PBKDF2CipherProviderGroovyTest.groovy
 
b/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/PBKDF2CipherProviderGroovyTest.groovy
index 795f3dc..c03795b 100644
--- 
a/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/PBKDF2CipherProviderGroovyTest.groovy
+++ 
b/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/PBKDF2CipherProviderGroovyTest.groovy
@@ -35,6 +35,8 @@ import static org.junit.Assert.assertTrue
 class PBKDF2CipherProviderGroovyTest {
     private static final Logger logger = 
LoggerFactory.getLogger(PBKDF2CipherProviderGroovyTest.class)
 
+    private static final String PLAINTEXT = "ExactBlockSizeRequiredForProcess"
+
     private static List<EncryptionMethod> strongKDFEncryptionMethods
 
     public static final String MICROBENCHMARK = "microbenchmark"
@@ -79,8 +81,6 @@ class PBKDF2CipherProviderGroovyTest {
         final String PASSWORD = "shortPassword"
         final byte[] SALT = Hex.decodeHex(SALT_HEX as char[])
 
-        final String plaintext = "This is a plaintext message."
-
         // Act
         for (EncryptionMethod em : strongKDFEncryptionMethods) {
             logger.info("Using algorithm: ${em.getAlgorithm()}")
@@ -90,7 +90,7 @@ class PBKDF2CipherProviderGroovyTest {
             byte[] iv = cipher.getIV()
             logger.info("IV: ${Hex.encodeHexString(iv)}")
 
-            byte[] cipherBytes = cipher.doFinal(plaintext.getBytes("UTF-8"))
+            byte[] cipherBytes = cipher.doFinal(PLAINTEXT.getBytes("UTF-8"))
             logger.info("Cipher text: ${Hex.encodeHexString(cipherBytes)} 
${cipherBytes.length}")
 
             cipher = cipherProvider.getCipher(em, PASSWORD, SALT, iv, 
DEFAULT_KEY_LENGTH, false)
@@ -99,7 +99,7 @@ class PBKDF2CipherProviderGroovyTest {
             logger.info("Recovered: ${recovered}")
 
             // Assert
-            assert plaintext.equals(recovered)
+            assert PLAINTEXT.equals(recovered)
         }
     }
 
@@ -140,8 +140,6 @@ class PBKDF2CipherProviderGroovyTest {
         final byte[] SALT = Hex.decodeHex(SALT_HEX as char[])
         final byte[] IV = Hex.decodeHex(IV_HEX as char[])
 
-        final String plaintext = "This is a plaintext message."
-
         // Act
         for (EncryptionMethod em : strongKDFEncryptionMethods) {
             logger.info("Using algorithm: ${em.getAlgorithm()}")
@@ -150,7 +148,7 @@ class PBKDF2CipherProviderGroovyTest {
             Cipher cipher = cipherProvider.getCipher(em, PASSWORD, SALT, IV, 
DEFAULT_KEY_LENGTH, true)
             logger.info("IV: ${Hex.encodeHexString(IV)}")
 
-            byte[] cipherBytes = cipher.doFinal(plaintext.getBytes("UTF-8"))
+            byte[] cipherBytes = cipher.doFinal(PLAINTEXT.getBytes("UTF-8"))
             logger.info("Cipher text: ${Hex.encodeHexString(cipherBytes)} 
${cipherBytes.length}")
 
             cipher = cipherProvider.getCipher(em, PASSWORD, SALT, IV, 
DEFAULT_KEY_LENGTH, false)
@@ -159,7 +157,7 @@ class PBKDF2CipherProviderGroovyTest {
             logger.info("Recovered: ${recovered}")
 
             // Assert
-            assert plaintext.equals(recovered)
+            assert PLAINTEXT.equals(recovered)
         }
     }
 
@@ -176,8 +174,6 @@ class PBKDF2CipherProviderGroovyTest {
 
         final int LONG_KEY_LENGTH = 256
 
-        final String plaintext = "This is a plaintext message."
-
         // Act
         for (EncryptionMethod em : strongKDFEncryptionMethods) {
             logger.info("Using algorithm: ${em.getAlgorithm()}")
@@ -187,7 +183,7 @@ class PBKDF2CipherProviderGroovyTest {
             byte[] iv = cipher.getIV()
             logger.info("IV: ${Hex.encodeHexString(iv)}")
 
-            byte[] cipherBytes = cipher.doFinal(plaintext.getBytes("UTF-8"))
+            byte[] cipherBytes = cipher.doFinal(PLAINTEXT.getBytes("UTF-8"))
             logger.info("Cipher text: ${Hex.encodeHexString(cipherBytes)} 
${cipherBytes.length}")
 
             cipher = cipherProvider.getCipher(em, PASSWORD, SALT, iv, 
LONG_KEY_LENGTH, false)
@@ -196,7 +192,7 @@ class PBKDF2CipherProviderGroovyTest {
             logger.info("Recovered: ${recovered}")
 
             // Assert
-            assert plaintext.equals(recovered)
+            assert PLAINTEXT.equals(recovered)
         }
     }
 
@@ -209,7 +205,6 @@ class PBKDF2CipherProviderGroovyTest {
         final byte[] SALT = Hex.decodeHex(SALT_HEX as char[])
         final byte[] IV = Hex.decodeHex(IV_HEX as char[])
 
-        final String plaintext = "This is a plaintext message."
         final EncryptionMethod encryptionMethod = EncryptionMethod.AES_CBC
         String prf = ""
 
@@ -232,7 +227,6 @@ class PBKDF2CipherProviderGroovyTest {
         final byte[] SALT = Hex.decodeHex(SALT_HEX as char[])
         final byte[] IV = Hex.decodeHex(IV_HEX as char[])
 
-        final String plaintext = "This is a plaintext message."
         final EncryptionMethod encryptionMethod = EncryptionMethod.AES_CBC
 
         final PBKDF2CipherProvider SHA512_PROVIDER = new 
PBKDF2CipherProvider(DEFAULT_PRF, TEST_ITERATION_COUNT)
@@ -249,7 +243,7 @@ class PBKDF2CipherProviderGroovyTest {
         Cipher cipher = cipherProvider.getCipher(encryptionMethod, PASSWORD, 
SALT, IV, DEFAULT_KEY_LENGTH, true)
         logger.info("IV: ${Hex.encodeHexString(IV)}")
 
-        byte[] cipherBytes = cipher.doFinal(plaintext.getBytes("UTF-8"))
+        byte[] cipherBytes = cipher.doFinal(PLAINTEXT.getBytes("UTF-8"))
         logger.info("Cipher text: ${Hex.encodeHexString(cipherBytes)} 
${cipherBytes.length}")
 
         cipher = SHA512_PROVIDER.getCipher(encryptionMethod, PASSWORD, SALT, 
IV, DEFAULT_KEY_LENGTH, false)
@@ -258,7 +252,7 @@ class PBKDF2CipherProviderGroovyTest {
         logger.info("Recovered: ${recovered}")
 
         // Assert
-        assert plaintext.equals(recovered)
+        assert PLAINTEXT.equals(recovered)
     }
 
     @Test
@@ -271,7 +265,6 @@ class PBKDF2CipherProviderGroovyTest {
         final byte[] SALT = Hex.decodeHex(SALT_HEX as char[])
         final byte[] IV = Hex.decodeHex(IV_HEX as char[])
 
-        final String plaintext = "This is a plaintext message."
         final EncryptionMethod encryptionMethod = EncryptionMethod.AES_CBC
 
         // Act
@@ -286,7 +279,7 @@ class PBKDF2CipherProviderGroovyTest {
             Cipher cipher = cipherProvider.getCipher(encryptionMethod, 
PASSWORD, SALT, IV, DEFAULT_KEY_LENGTH, true)
             logger.info("IV: ${Hex.encodeHexString(IV)}")
 
-            byte[] cipherBytes = cipher.doFinal(plaintext.getBytes("UTF-8"))
+            byte[] cipherBytes = cipher.doFinal(PLAINTEXT.getBytes("UTF-8"))
             logger.info("Cipher text: ${Hex.encodeHexString(cipherBytes)} 
${cipherBytes.length}")
 
             cipher = cipherProvider.getCipher(encryptionMethod, PASSWORD, 
SALT, IV, DEFAULT_KEY_LENGTH, false)
@@ -295,7 +288,7 @@ class PBKDF2CipherProviderGroovyTest {
             logger.info("Recovered: ${recovered}")
 
             // Assert
-            assert plaintext.equals(recovered)
+            assert PLAINTEXT.equals(recovered)
         }
     }
 
@@ -334,7 +327,6 @@ class PBKDF2CipherProviderGroovyTest {
         RandomIVPBECipherProvider sha256CP = new 
PBKDF2CipherProvider("SHA-256", TEST_ITERATION_COUNT)
         RandomIVPBECipherProvider sha512CP = new 
PBKDF2CipherProvider("SHA-512", TEST_ITERATION_COUNT)
 
-        final String PLAINTEXT = "This is a plaintext message."
         final String PASSWORD = "thisIsABadPassword"
         final byte[] SALT = [0x11] * 16
         final byte[] IV = [0x22] * 16
@@ -370,8 +362,6 @@ class PBKDF2CipherProviderGroovyTest {
         final byte[] SALT = Hex.decodeHex(SALT_HEX as char[])
         final byte[] IV = Hex.decodeHex(IV_HEX as char[])
 
-        final String plaintext = "This is a plaintext message."
-
         // Act
         for (EncryptionMethod em : strongKDFEncryptionMethods) {
             logger.info("Using algorithm: ${em.getAlgorithm()}")
@@ -380,7 +370,7 @@ class PBKDF2CipherProviderGroovyTest {
             Cipher cipher = cipherProvider.getCipher(em, PASSWORD, SALT, IV, 
DEFAULT_KEY_LENGTH, true)
             logger.info("IV: ${Hex.encodeHexString(IV)}")
 
-            byte[] cipherBytes = cipher.doFinal(plaintext.getBytes("UTF-8"))
+            byte[] cipherBytes = cipher.doFinal(PLAINTEXT.getBytes("UTF-8"))
             logger.info("Cipher text: ${Hex.encodeHexString(cipherBytes)} 
${cipherBytes.length}")
 
             def msg = shouldFail(IllegalArgumentException) {
@@ -426,8 +416,6 @@ class PBKDF2CipherProviderGroovyTest {
         final byte[] SALT = Hex.decodeHex(SALT_HEX as char[])
         final byte[] IV = Hex.decodeHex(IV_HEX as char[])
 
-        final String PLAINTEXT = "This is a plaintext message."
-
         // Currently only AES ciphers are compatible with PBKDF2, so redundant 
to test all algorithms
         final def VALID_KEY_LENGTHS = AES_KEY_LENGTHS
         EncryptionMethod encryptionMethod = EncryptionMethod.AES_CBC
diff --git 
a/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/ScryptCipherProviderGroovyTest.groovy
 
b/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/ScryptCipherProviderGroovyTest.groovy
index d6dd5b3..2a92b1f 100644
--- 
a/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/ScryptCipherProviderGroovyTest.groovy
+++ 
b/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/crypto/ScryptCipherProviderGroovyTest.groovy
@@ -46,6 +46,8 @@ import static org.junit.Assert.assertTrue
 class ScryptCipherProviderGroovyTest {
     private static final Logger logger = 
LoggerFactory.getLogger(ScryptCipherProviderGroovyTest.class)
 
+    private static final String PLAINTEXT = "ExactBlockSizeRequiredForProcess"
+
     private static List<EncryptionMethod> strongKDFEncryptionMethods
 
     private static final int DEFAULT_KEY_LENGTH = 128
@@ -88,8 +90,6 @@ class ScryptCipherProviderGroovyTest {
         final String PASSWORD = "shortPassword"
         final byte[] SALT = cipherProvider.generateSalt()
 
-        final String plaintext = "This is a plaintext message."
-
         // Act
         for (EncryptionMethod em : strongKDFEncryptionMethods) {
             logger.info("Using algorithm: ${em.getAlgorithm()}")
@@ -99,7 +99,7 @@ class ScryptCipherProviderGroovyTest {
             byte[] iv = cipher.getIV()
             logger.info("IV: ${Hex.encodeHexString(iv)}")
 
-            byte[] cipherBytes = cipher.doFinal(plaintext.getBytes("UTF-8"))
+            byte[] cipherBytes = cipher.doFinal(PLAINTEXT.getBytes("UTF-8"))
             logger.info("Cipher text: ${Hex.encodeHexString(cipherBytes)} 
${cipherBytes.length}")
 
             cipher = cipherProvider.getCipher(em, PASSWORD, SALT, iv, 
DEFAULT_KEY_LENGTH, false)
@@ -108,7 +108,7 @@ class ScryptCipherProviderGroovyTest {
             logger.info("Recovered: ${recovered}")
 
             // Assert
-            assert plaintext.equals(recovered)
+            assert PLAINTEXT.equals(recovered)
         }
     }
 
@@ -119,8 +119,6 @@ class ScryptCipherProviderGroovyTest {
         final byte[] SALT = cipherProvider.generateSalt()
         final byte[] IV = Hex.decodeHex("01" * 16 as char[])
 
-        final String plaintext = "This is a plaintext message."
-
         // Act
         for (EncryptionMethod em : strongKDFEncryptionMethods) {
             logger.info("Using algorithm: ${em.getAlgorithm()}")
@@ -129,7 +127,7 @@ class ScryptCipherProviderGroovyTest {
             Cipher cipher = cipherProvider.getCipher(em, PASSWORD, SALT, IV, 
DEFAULT_KEY_LENGTH, true)
             logger.info("IV: ${Hex.encodeHexString(IV)}")
 
-            byte[] cipherBytes = cipher.doFinal(plaintext.getBytes("UTF-8"))
+            byte[] cipherBytes = cipher.doFinal(PLAINTEXT.getBytes("UTF-8"))
             logger.info("Cipher text: ${Hex.encodeHexString(cipherBytes)} 
${cipherBytes.length}")
 
             cipher = cipherProvider.getCipher(em, PASSWORD, SALT, IV, 
DEFAULT_KEY_LENGTH, false)
@@ -138,7 +136,7 @@ class ScryptCipherProviderGroovyTest {
             logger.info("Recovered: ${recovered}")
 
             // Assert
-            assert plaintext.equals(recovered)
+            assert PLAINTEXT.equals(recovered)
         }
     }
 
@@ -153,8 +151,6 @@ class ScryptCipherProviderGroovyTest {
 
         final int LONG_KEY_LENGTH = 256
 
-        final String plaintext = "This is a plaintext message."
-
         // Act
         for (EncryptionMethod em : strongKDFEncryptionMethods) {
             logger.info("Using algorithm: ${em.getAlgorithm()}")
@@ -164,7 +160,7 @@ class ScryptCipherProviderGroovyTest {
             byte[] iv = cipher.getIV()
             logger.info("IV: ${Hex.encodeHexString(iv)}")
 
-            byte[] cipherBytes = cipher.doFinal(plaintext.getBytes("UTF-8"))
+            byte[] cipherBytes = cipher.doFinal(PLAINTEXT.getBytes("UTF-8"))
             logger.info("Cipher text: ${Hex.encodeHexString(cipherBytes)} 
${cipherBytes.length}")
 
             cipher = cipherProvider.getCipher(em, PASSWORD, SALT, iv, 
LONG_KEY_LENGTH, false)
@@ -173,7 +169,7 @@ class ScryptCipherProviderGroovyTest {
             logger.info("Recovered: ${recovered}")
 
             // Assert
-            assert plaintext.equals(recovered)
+            assert PLAINTEXT.equals(recovered)
         }
     }
 
@@ -265,7 +261,6 @@ class ScryptCipherProviderGroovyTest {
         final String EXPECTED_FORMATTED_SALT = 
cipherProvider.formatSaltForScrypt(SALT)
         logger.info("Expected salt: ${EXPECTED_FORMATTED_SALT}")
 
-        final String plaintext = "This is a plaintext message."
         EncryptionMethod encryptionMethod = EncryptionMethod.AES_CBC
         logger.info("Using algorithm: ${encryptionMethod.getAlgorithm()}")
 
@@ -276,7 +271,7 @@ class ScryptCipherProviderGroovyTest {
         byte[] iv = cipher.getIV()
         logger.info("IV: ${Hex.encodeHexString(iv)}")
 
-        byte[] cipherBytes = cipher.doFinal(plaintext.getBytes("UTF-8"))
+        byte[] cipherBytes = cipher.doFinal(PLAINTEXT.getBytes("UTF-8"))
         logger.info("Cipher text: ${Hex.encodeHexString(cipherBytes)} 
${cipherBytes.length}")
 
         // Manually initialize a cipher for decrypt with the expected salt
@@ -294,7 +289,7 @@ class ScryptCipherProviderGroovyTest {
         logger.info("Recovered: ${recovered}")
 
         // Assert
-        assert plaintext.equals(recovered)
+        assert PLAINTEXT.equals(recovered)
     }
 
     @Test
@@ -368,8 +363,6 @@ class ScryptCipherProviderGroovyTest {
         final byte[] SALT = cipherProvider.generateSalt()
         final byte[] IV = Hex.decodeHex("00" * 16 as char[])
 
-        final String plaintext = "This is a plaintext message."
-
         // Act
         for (EncryptionMethod em : strongKDFEncryptionMethods) {
             logger.info("Using algorithm: ${em.getAlgorithm()}")
@@ -378,7 +371,7 @@ class ScryptCipherProviderGroovyTest {
             Cipher cipher = cipherProvider.getCipher(em, PASSWORD, SALT, IV, 
DEFAULT_KEY_LENGTH, true)
             logger.info("IV: ${Hex.encodeHexString(IV)}")
 
-            byte[] cipherBytes = cipher.doFinal(plaintext.getBytes("UTF-8"))
+            byte[] cipherBytes = cipher.doFinal(PLAINTEXT.getBytes("UTF-8"))
             logger.info("Cipher text: ${Hex.encodeHexString(cipherBytes)} 
${cipherBytes.length}")
 
             def msg = shouldFail(IllegalArgumentException) {
@@ -398,8 +391,6 @@ class ScryptCipherProviderGroovyTest {
         final byte[] SALT = cipherProvider.generateSalt()
         final byte[] IV = Hex.decodeHex("01" * 16 as char[])
 
-        final String PLAINTEXT = "This is a plaintext message."
-
         final def VALID_KEY_LENGTHS = AES_KEY_LENGTHS
         EncryptionMethod encryptionMethod = EncryptionMethod.AES_CBC
 
@@ -431,8 +422,6 @@ class ScryptCipherProviderGroovyTest {
         final byte[] SALT = cipherProvider.generateSalt()
         final byte[] IV = Hex.decodeHex("00" * 16 as char[])
 
-        final String PLAINTEXT = "This is a plaintext message."
-
         // Even though Scrypt can derive keys of arbitrary length, it will 
fail to validate if the underlying cipher does not support it
         final def INVALID_KEY_LENGTHS = [-1, 40, 64, 112, 512]
         // Currently only AES ciphers are compatible with Scrypt, so redundant 
to test all algorithms
diff --git 
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/EncryptContent.java
 
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/EncryptContent.java
index f083379..522980c 100644
--- 
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/EncryptContent.java
+++ 
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/EncryptContent.java
@@ -322,8 +322,8 @@ public class EncryptContent extends AbstractProcessor {
         final String password = context.getProperty(PASSWORD).getValue();
         final KeyDerivationFunction kdf = 
KeyDerivationFunction.valueOf(context.getProperty(KEY_DERIVATION_FUNCTION).getValue());
         final String keyHex = context.getProperty(RAW_KEY_HEX).getValue();
+        final boolean encrypt = 
context.getProperty(MODE).getValue().equalsIgnoreCase(ENCRYPT_MODE);
         if (isPGPAlgorithm(algorithm)) {
-            final boolean encrypt = 
context.getProperty(MODE).getValue().equalsIgnoreCase(ENCRYPT_MODE);
             final String publicKeyring = 
context.getProperty(PUBLIC_KEYRING).getValue();
             final String publicUserId = 
context.getProperty(PUBLIC_KEY_USERID).getValue();
             final String privateKeyring = 
context.getProperty(PRIVATE_KEYRING).getValue();
@@ -334,7 +334,7 @@ public class EncryptContent extends AbstractProcessor {
         } else { // Not PGP
             boolean allowWeakCrypto = 
context.getProperty(ALLOW_WEAK_CRYPTO).getValue().equalsIgnoreCase(WEAK_CRYPTO_ALLOWED_NAME);
             if (encryptionMethod.isKeyedCipher()) { // Raw key or derived key 
from password
-                validationResults.addAll(validateKeyed(encryptionMethod, kdf, 
keyHex, password, allowWeakCrypto));
+                validationResults.addAll(validateKeyed(encryptionMethod, kdf, 
keyHex, password, allowWeakCrypto, encrypt));
             } else { // PBE
                 validationResults.addAll(validatePBE(encryptionMethod, kdf, 
password, allowWeakCrypto));
             }
@@ -479,7 +479,7 @@ public class EncryptContent extends AbstractProcessor {
     }
 
 
-    private List<ValidationResult> validateKeyed(EncryptionMethod 
encryptionMethod, KeyDerivationFunction kdf, String keyHex, String password, 
boolean allowWeakCrypto) {
+    private List<ValidationResult> validateKeyed(EncryptionMethod 
encryptionMethod, KeyDerivationFunction kdf, String keyHex, String password, 
boolean allowWeakCrypto, boolean encrypt) {
         List<ValidationResult> validationResults = new ArrayList<>();
         boolean limitedStrengthCrypto = 
!CipherUtility.isUnlimitedStrengthCryptoSupported();
 
@@ -526,6 +526,17 @@ public class EncryptContent extends AbstractProcessor {
                     .explanation(KEY_DERIVATION_FUNCTION.getDisplayName() + " 
is required to be " + StringUtils.join(kdfsForKeyedCipher, ", ") + " when using 
algorithm " +
                             encryptionMethod.getAlgorithm()).build());
         }
+
+        if (encrypt && EncryptionMethod.AES_CBC_NO_PADDING == 
encryptionMethod) {
+            validationResults.add(new ValidationResult.Builder()
+                    .subject(ENCRYPTION_ALGORITHM.getDisplayName())
+                    .input(encryptionMethod.name())
+                    .explanation(String.format("Encryption not supported for 
[%s]", encryptionMethod.getAlgorithm()))
+                    .valid(false)
+                    .build()
+            );
+        }
+
         return validationResults;
     }
 
diff --git 
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/groovy/org/apache/nifi/processors/standard/TestEncryptContentGroovy.groovy
 
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/groovy/org/apache/nifi/processors/standard/TestEncryptContentGroovy.groovy
index 1e7d6f9..15b3f6d 100644
--- 
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/groovy/org/apache/nifi/processors/standard/TestEncryptContentGroovy.groovy
+++ 
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/groovy/org/apache/nifi/processors/standard/TestEncryptContentGroovy.groovy
@@ -25,6 +25,7 @@ import org.apache.nifi.security.util.KeyDerivationFunction
 import org.apache.nifi.security.util.crypto.Argon2CipherProvider
 import org.apache.nifi.security.util.crypto.Argon2SecureHasher
 import org.apache.nifi.security.util.crypto.CipherUtility
+import org.apache.nifi.security.util.crypto.KeyedEncryptor
 import org.apache.nifi.security.util.crypto.PasswordBasedEncryptor
 import org.apache.nifi.security.util.crypto.RandomIVPBECipherProvider
 import org.apache.nifi.util.MockFlowFile
@@ -58,6 +59,8 @@ class TestEncryptContentGroovy {
     private static final String WEAK_CRYPTO_ALLOWED = 
EncryptContent.WEAK_CRYPTO_ALLOWED_NAME
     private static final String WEAK_CRYPTO_NOT_ALLOWED = 
EncryptContent.WEAK_CRYPTO_NOT_ALLOWED_NAME
 
+    private static final List<EncryptionMethod> 
SUPPORTED_KEYED_ENCRYPTION_METHODS = EncryptionMethod.values().findAll { 
it.isKeyedCipher() && it != EncryptionMethod.AES_CBC_NO_PADDING }
+
     @BeforeClass
     static void setUpOnce() throws Exception {
         Security.addProvider(new BouncyCastleProvider())
@@ -198,15 +201,13 @@ class TestEncryptContentGroovy {
         Collection<ValidationResult> results
         MockProcessContext pc
 
-        def encryptionMethods = EncryptionMethod.values().findAll { 
it.isKeyedCipher() }
-
         final int VALID_KEY_LENGTH = 128
         final String VALID_KEY_HEX = "ab" * (VALID_KEY_LENGTH / 8)
         logger.info("Using key ${VALID_KEY_HEX} (${VALID_KEY_HEX.length() * 4} 
bits)")
 
         runner.setProperty(EncryptContent.MODE, EncryptContent.ENCRYPT_MODE)
 
-        encryptionMethods.each { EncryptionMethod encryptionMethod ->
+        SUPPORTED_KEYED_ENCRYPTION_METHODS.each { EncryptionMethod 
encryptionMethod ->
             logger.info("Trying encryption method ${encryptionMethod.name()}")
             runner.setProperty(EncryptContent.ENCRYPTION_ALGORITHM, 
encryptionMethod.name())
 
@@ -315,8 +316,7 @@ class TestEncryptContentGroovy {
         Collection<ValidationResult> results
         MockProcessContext pc
 
-        def keyedEncryptionMethods = EncryptionMethod.values().findAll { 
it.isKeyedCipher() }
-        logger.info("Testing keyed encryption methods: 
${keyedEncryptionMethods*.name()}")
+        logger.info("Testing keyed encryption methods: 
${SUPPORTED_KEYED_ENCRYPTION_METHODS*.name()}")
 
         final int VALID_KEY_LENGTH = 128
         final String VALID_KEY_HEX = "ab" * (VALID_KEY_LENGTH / 8)
@@ -330,7 +330,7 @@ class TestEncryptContentGroovy {
         final def VALID_KDFS = KeyDerivationFunction.values().findAll { 
it.isStrongKDF() }
 
         // Scenario 1 - RKH w/ KDF NONE & em in [CBC, CTR, GCM] (no password)
-        keyedEncryptionMethods.each { EncryptionMethod kem ->
+        SUPPORTED_KEYED_ENCRYPTION_METHODS.each { EncryptionMethod kem ->
             logger.info("Trying encryption method ${kem.name()} with KDF 
${none.name()}")
             runner.setProperty(EncryptContent.ENCRYPTION_ALGORITHM, kem.name())
             runner.setProperty(EncryptContent.KEY_DERIVATION_FUNCTION, 
none.name())
@@ -440,9 +440,7 @@ class TestEncryptContentGroovy {
         testRunner.setProperty(EncryptContent.RAW_KEY_HEX, RAW_KEY_HEX)
         testRunner.setProperty(EncryptContent.KEY_DERIVATION_FUNCTION, 
KeyDerivationFunction.NONE.name())
 
-        def keyedCipherEMs = EncryptionMethod.values().findAll { 
it.isKeyedCipher() }
-
-        keyedCipherEMs.each { EncryptionMethod encryptionMethod ->
+        SUPPORTED_KEYED_ENCRYPTION_METHODS.each { EncryptionMethod 
encryptionMethod ->
             logger.info("Attempting {}", encryptionMethod.name())
             testRunner.setProperty(EncryptContent.ENCRYPTION_ALGORITHM, 
encryptionMethod.name())
             testRunner.setProperty(EncryptContent.MODE, 
EncryptContent.ENCRYPT_MODE)
@@ -469,6 +467,33 @@ class TestEncryptContentGroovy {
         }
     }
 
+    @Test
+    void testDecryptAesCbcNoPadding() {
+        final TestRunner testRunner = TestRunners.newTestRunner(new 
EncryptContent())
+        final String RAW_KEY_HEX = "ab" * 16
+        testRunner.setProperty(EncryptContent.RAW_KEY_HEX, RAW_KEY_HEX)
+        testRunner.setProperty(EncryptContent.KEY_DERIVATION_FUNCTION, 
KeyDerivationFunction.NONE.name())
+        testRunner.setProperty(EncryptContent.ENCRYPTION_ALGORITHM, 
EncryptionMethod.AES_CBC_NO_PADDING.name())
+        testRunner.setProperty(EncryptContent.MODE, 
EncryptContent.DECRYPT_MODE)
+
+        final String content = "ExactBlockSizeRequiredForProcess"
+        final byte[] bytes = content.getBytes(StandardCharsets.UTF_8)
+        final ByteArrayInputStream inputStream = new 
ByteArrayInputStream(bytes)
+        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream()
+
+        final KeyedEncryptor encryptor = new 
KeyedEncryptor(EncryptionMethod.AES_CBC_NO_PADDING, Hex.decodeHex(RAW_KEY_HEX))
+        encryptor.encryptionCallback.process(inputStream, outputStream)
+        outputStream.close()
+
+        final byte[] encrypted = outputStream.toByteArray()
+        testRunner.enqueue(encrypted)
+        testRunner.run()
+
+        testRunner.assertAllFlowFilesTransferred(EncryptContent.REL_SUCCESS, 1)
+        MockFlowFile flowFile = 
testRunner.getFlowFilesForRelationship(EncryptContent.REL_SUCCESS).get(0)
+        flowFile.assertContentEquals(content)
+    }
+
     // TODO: Implement
     @Test
     void testArgon2EncryptionShouldWriteAttributesWithEncryptionMetadata() 
throws IOException {

Reply via email to