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 {