NIFI-11161 Simplified KeyedCipherPropertyEncryptor

- Replaced KeyedCipherProvider references with direct Cipher instantiation

This closes #6939
Signed-off-by: Paul Grey <greyp@apache.org>
This commit is contained in:
exceptionfactory 2023-02-09 16:19:05 -06:00 committed by Paul Grey
parent b08ae75be4
commit 9773105841
No known key found for this signature in database
GPG Key ID: 8DDF32B9C7EE39D0
3 changed files with 26 additions and 45 deletions

View File

@ -16,30 +16,24 @@
*/
package org.apache.nifi.encrypt;
import org.apache.nifi.security.util.EncryptionMethod;
import org.apache.nifi.security.util.crypto.KeyedCipherProvider;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Objects;
/**
* Property Encryptor implementation using Keyed Cipher Provider
* Property Encryptor implementation using AES-GCM
*/
class KeyedCipherPropertyEncryptor extends CipherPropertyEncryptor {
private static final int INITIALIZATION_VECTOR_LENGTH = 16;
private static final int GCM_TAG_LENGTH_BITS = 128;
private static final int ARRAY_START = 0;
private static final boolean ENCRYPT = true;
private static final boolean DECRYPT = false;
private final KeyedCipherProvider cipherProvider;
private final EncryptionMethod encryptionMethod;
private static final String CIPHER_ALGORITHM = "AES/GCM/NoPadding";
private final SecretKey secretKey;
@ -47,16 +41,11 @@ class KeyedCipherPropertyEncryptor extends CipherPropertyEncryptor {
private final String description;
protected KeyedCipherPropertyEncryptor(final KeyedCipherProvider cipherProvider,
final EncryptionMethod encryptionMethod,
final SecretKey secretKey) {
this.cipherProvider = cipherProvider;
this.encryptionMethod = encryptionMethod;
protected KeyedCipherPropertyEncryptor(final SecretKey secretKey) {
this.secretKey = secretKey;
this.secureRandom = new SecureRandom();
this.description = String.format("%s Encryption Method [%s] Key Algorithm [%s] Key Bytes [%d]",
this.description = String.format("%s Key Algorithm [%s] Key Bytes [%d]",
getClass().getSimpleName(),
encryptionMethod.getAlgorithm(),
secretKey.getAlgorithm(),
secretKey.getEncoded().length);
}
@ -70,7 +59,7 @@ class KeyedCipherPropertyEncryptor extends CipherPropertyEncryptor {
@Override
protected Cipher getDecryptionCipher(final byte[] encryptedBinary) {
final byte[] initializationVector = readInitializationVector(encryptedBinary);
return getCipher(initializationVector, DECRYPT);
return getCipher(initializationVector, Cipher.DECRYPT_MODE);
}
/**
@ -81,7 +70,7 @@ class KeyedCipherPropertyEncryptor extends CipherPropertyEncryptor {
*/
@Override
protected Cipher getEncryptionCipher(byte[] encodedParameters) {
return getCipher(encodedParameters, ENCRYPT);
return getCipher(encodedParameters, Cipher.ENCRYPT_MODE);
}
/**
@ -107,11 +96,14 @@ class KeyedCipherPropertyEncryptor extends CipherPropertyEncryptor {
return initializationVector;
}
private Cipher getCipher(final byte[] initializationVector, final boolean encrypt) {
private Cipher getCipher(final byte[] initializationVector, final int cipherMode) {
try {
return cipherProvider.getCipher(encryptionMethod, secretKey, initializationVector, encrypt);
final Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
final GCMParameterSpec parameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH_BITS, initializationVector);
cipher.init(cipherMode, secretKey, parameterSpec);
return cipher;
} catch (final Exception e) {
final String message = String.format("Failed to get Cipher for Algorithm [%s]", encryptionMethod.getAlgorithm());
final String message = String.format("Failed to get Cipher for Algorithm [%s]", CIPHER_ALGORITHM);
throw new EncryptionException(message, e);
}
}
@ -123,7 +115,7 @@ class KeyedCipherPropertyEncryptor extends CipherPropertyEncryptor {
}
/**
* Return object equality based on Encryption Method and Secret Key
* Return object equality based on Secret Key
*
* @param object Object for comparison
* @return Object equality status
@ -135,19 +127,19 @@ class KeyedCipherPropertyEncryptor extends CipherPropertyEncryptor {
equals = true;
} else if (object instanceof KeyedCipherPropertyEncryptor) {
final KeyedCipherPropertyEncryptor encryptor = (KeyedCipherPropertyEncryptor) object;
equals = Objects.equals(encryptionMethod, encryptor.encryptionMethod) && Objects.equals(secretKey, encryptor.secretKey);
equals = Objects.equals(secretKey, encryptor.secretKey);
}
return equals;
}
/**
* Return hash code based on Encryption Method and Secret Key
* Return hash code based on Secret Key
*
* @return Hash Code based on Encryption Method and Secret Key
* @return Hash Code based on Secret Key
*/
@Override
public int hashCode() {
return Objects.hash(encryptionMethod, secretKey);
return Objects.hash(secretKey);
}
/**

View File

@ -17,8 +17,6 @@
package org.apache.nifi.encrypt;
import org.apache.nifi.security.util.EncryptionMethod;
import org.apache.nifi.security.util.crypto.AESKeyedCipherProvider;
import org.apache.nifi.security.util.crypto.KeyedCipherProvider;
import org.apache.nifi.security.util.crypto.PBECipherProvider;
import javax.crypto.SecretKey;
@ -66,10 +64,8 @@ public class PropertyEncryptorBuilder {
if (propertyEncryptionMethod == null) {
return getPasswordBasedCipherPropertyEncryptor();
} else {
final KeyedCipherProvider keyedCipherProvider = new AESKeyedCipherProvider();
final SecretKey secretKey = SECRET_KEY_PROVIDER.getSecretKey(propertyEncryptionMethod, password);
final EncryptionMethod encryptionMethod = propertyEncryptionMethod.getEncryptionMethod();
return new KeyedCipherPropertyEncryptor(keyedCipherProvider, encryptionMethod, secretKey);
return new KeyedCipherPropertyEncryptor(secretKey);
}
}

View File

@ -18,9 +18,6 @@ package org.apache.nifi.encrypt;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.nifi.security.util.EncryptionMethod;
import org.apache.nifi.security.util.crypto.AESKeyedCipherProvider;
import org.apache.nifi.security.util.crypto.KeyedCipherProvider;
import org.apache.nifi.util.StringUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@ -41,10 +38,6 @@ public class KeyedCipherPropertyEncryptorTest {
private static final int ENCRYPTED_BINARY_LENGTH = 48;
private static final KeyedCipherProvider CIPHER_PROVIDER = new AESKeyedCipherProvider();
private static final EncryptionMethod ENCRYPTION_METHOD = EncryptionMethod.AES_GCM;
private static final String KEY_ALGORITHM = "AES";
private static final byte[] STATIC_KEY = StringUtils.repeat("KEY", 8).getBytes(DEFAULT_CHARSET);
@ -57,7 +50,7 @@ public class KeyedCipherPropertyEncryptorTest {
@BeforeEach
public void setUp() {
encryptor = new KeyedCipherPropertyEncryptor(CIPHER_PROVIDER, ENCRYPTION_METHOD, SECRET_KEY);
encryptor = new KeyedCipherPropertyEncryptor(SECRET_KEY);
}
@Test
@ -77,18 +70,18 @@ public class KeyedCipherPropertyEncryptorTest {
@Test
public void testDecryptEncryptionException() {
final String encodedProperty = Hex.encodeHexString(PROPERTY.getBytes(DEFAULT_CHARSET));
assertThrows(EncryptionException.class, () -> encryptor.decrypt(encodedProperty));
assertThrows(Exception.class, () -> encryptor.decrypt(encodedProperty));
}
@Test
public void testGetCipherEncryptionException() {
encryptor = new KeyedCipherPropertyEncryptor(CIPHER_PROVIDER, ENCRYPTION_METHOD, INVALID_SECRET_KEY);
encryptor = new KeyedCipherPropertyEncryptor(INVALID_SECRET_KEY);
assertThrows(EncryptionException.class, () -> encryptor.encrypt(PROPERTY));
}
@Test
public void testEqualsHashCode() {
final KeyedCipherPropertyEncryptor equivalentEncryptor = new KeyedCipherPropertyEncryptor(CIPHER_PROVIDER, ENCRYPTION_METHOD, SECRET_KEY);
final KeyedCipherPropertyEncryptor equivalentEncryptor = new KeyedCipherPropertyEncryptor(SECRET_KEY);
assertEquals(encryptor, equivalentEncryptor);
assertEquals(encryptor.hashCode(), equivalentEncryptor.hashCode());
}
@ -96,7 +89,7 @@ public class KeyedCipherPropertyEncryptorTest {
@Test
public void testEqualsHashCodeDifferentSecretKey() {
final SecretKey secretKey = new SecretKeySpec(String.class.getSimpleName().getBytes(StandardCharsets.UTF_8), KEY_ALGORITHM);
final KeyedCipherPropertyEncryptor differentEncryptor = new KeyedCipherPropertyEncryptor(CIPHER_PROVIDER, ENCRYPTION_METHOD, secretKey);
final KeyedCipherPropertyEncryptor differentEncryptor = new KeyedCipherPropertyEncryptor(secretKey);
assertNotEquals(encryptor, differentEncryptor);
assertNotEquals(encryptor.hashCode(), differentEncryptor.hashCode());
}