NIFI-8319 Added AES/CBC/NoPadding for decryption in EncryptContent Processor

Signed-off-by: Pierre Villard <pierre.villard.fr@gmail.com>

This closes #4894.
This commit is contained in:
exceptionfactory 2021-03-12 16:00:42 -06:00 committed by Pierre Villard
parent 8202bffc98
commit a7ba5bb4f8
No known key found for this signature in database
GPG Key ID: F92A93B30C07C6D5
9 changed files with 113 additions and 128 deletions

View File

@ -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);

View File

@ -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) {

View File

@ -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

View File

@ -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) {

View File

@ -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"]

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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 {