mirror of https://github.com/apache/nifi.git
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:
parent
b08ae75be4
commit
9773105841
|
@ -16,30 +16,24 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.encrypt;
|
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.Cipher;
|
||||||
import javax.crypto.SecretKey;
|
import javax.crypto.SecretKey;
|
||||||
|
import javax.crypto.spec.GCMParameterSpec;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Property Encryptor implementation using Keyed Cipher Provider
|
* Property Encryptor implementation using AES-GCM
|
||||||
*/
|
*/
|
||||||
class KeyedCipherPropertyEncryptor extends CipherPropertyEncryptor {
|
class KeyedCipherPropertyEncryptor extends CipherPropertyEncryptor {
|
||||||
private static final int INITIALIZATION_VECTOR_LENGTH = 16;
|
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 int ARRAY_START = 0;
|
||||||
|
|
||||||
private static final boolean ENCRYPT = true;
|
private static final String CIPHER_ALGORITHM = "AES/GCM/NoPadding";
|
||||||
|
|
||||||
private static final boolean DECRYPT = false;
|
|
||||||
|
|
||||||
private final KeyedCipherProvider cipherProvider;
|
|
||||||
|
|
||||||
private final EncryptionMethod encryptionMethod;
|
|
||||||
|
|
||||||
private final SecretKey secretKey;
|
private final SecretKey secretKey;
|
||||||
|
|
||||||
|
@ -47,16 +41,11 @@ class KeyedCipherPropertyEncryptor extends CipherPropertyEncryptor {
|
||||||
|
|
||||||
private final String description;
|
private final String description;
|
||||||
|
|
||||||
protected KeyedCipherPropertyEncryptor(final KeyedCipherProvider cipherProvider,
|
protected KeyedCipherPropertyEncryptor(final SecretKey secretKey) {
|
||||||
final EncryptionMethod encryptionMethod,
|
|
||||||
final SecretKey secretKey) {
|
|
||||||
this.cipherProvider = cipherProvider;
|
|
||||||
this.encryptionMethod = encryptionMethod;
|
|
||||||
this.secretKey = secretKey;
|
this.secretKey = secretKey;
|
||||||
this.secureRandom = new SecureRandom();
|
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(),
|
getClass().getSimpleName(),
|
||||||
encryptionMethod.getAlgorithm(),
|
|
||||||
secretKey.getAlgorithm(),
|
secretKey.getAlgorithm(),
|
||||||
secretKey.getEncoded().length);
|
secretKey.getEncoded().length);
|
||||||
}
|
}
|
||||||
|
@ -70,7 +59,7 @@ class KeyedCipherPropertyEncryptor extends CipherPropertyEncryptor {
|
||||||
@Override
|
@Override
|
||||||
protected Cipher getDecryptionCipher(final byte[] encryptedBinary) {
|
protected Cipher getDecryptionCipher(final byte[] encryptedBinary) {
|
||||||
final byte[] initializationVector = readInitializationVector(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
|
@Override
|
||||||
protected Cipher getEncryptionCipher(byte[] encodedParameters) {
|
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;
|
return initializationVector;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Cipher getCipher(final byte[] initializationVector, final boolean encrypt) {
|
private Cipher getCipher(final byte[] initializationVector, final int cipherMode) {
|
||||||
try {
|
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) {
|
} 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);
|
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
|
* @param object Object for comparison
|
||||||
* @return Object equality status
|
* @return Object equality status
|
||||||
|
@ -135,19 +127,19 @@ class KeyedCipherPropertyEncryptor extends CipherPropertyEncryptor {
|
||||||
equals = true;
|
equals = true;
|
||||||
} else if (object instanceof KeyedCipherPropertyEncryptor) {
|
} else if (object instanceof KeyedCipherPropertyEncryptor) {
|
||||||
final KeyedCipherPropertyEncryptor encryptor = (KeyedCipherPropertyEncryptor) object;
|
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 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
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(encryptionMethod, secretKey);
|
return Objects.hash(secretKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
package org.apache.nifi.encrypt;
|
package org.apache.nifi.encrypt;
|
||||||
|
|
||||||
import org.apache.nifi.security.util.EncryptionMethod;
|
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 org.apache.nifi.security.util.crypto.PBECipherProvider;
|
||||||
|
|
||||||
import javax.crypto.SecretKey;
|
import javax.crypto.SecretKey;
|
||||||
|
@ -66,10 +64,8 @@ public class PropertyEncryptorBuilder {
|
||||||
if (propertyEncryptionMethod == null) {
|
if (propertyEncryptionMethod == null) {
|
||||||
return getPasswordBasedCipherPropertyEncryptor();
|
return getPasswordBasedCipherPropertyEncryptor();
|
||||||
} else {
|
} else {
|
||||||
final KeyedCipherProvider keyedCipherProvider = new AESKeyedCipherProvider();
|
|
||||||
final SecretKey secretKey = SECRET_KEY_PROVIDER.getSecretKey(propertyEncryptionMethod, password);
|
final SecretKey secretKey = SECRET_KEY_PROVIDER.getSecretKey(propertyEncryptionMethod, password);
|
||||||
final EncryptionMethod encryptionMethod = propertyEncryptionMethod.getEncryptionMethod();
|
return new KeyedCipherPropertyEncryptor(secretKey);
|
||||||
return new KeyedCipherPropertyEncryptor(keyedCipherProvider, encryptionMethod, secretKey);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,9 +18,6 @@ package org.apache.nifi.encrypt;
|
||||||
|
|
||||||
import org.apache.commons.codec.DecoderException;
|
import org.apache.commons.codec.DecoderException;
|
||||||
import org.apache.commons.codec.binary.Hex;
|
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.apache.nifi.util.StringUtils;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
@ -41,10 +38,6 @@ public class KeyedCipherPropertyEncryptorTest {
|
||||||
|
|
||||||
private static final int ENCRYPTED_BINARY_LENGTH = 48;
|
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 String KEY_ALGORITHM = "AES";
|
||||||
|
|
||||||
private static final byte[] STATIC_KEY = StringUtils.repeat("KEY", 8).getBytes(DEFAULT_CHARSET);
|
private static final byte[] STATIC_KEY = StringUtils.repeat("KEY", 8).getBytes(DEFAULT_CHARSET);
|
||||||
|
@ -57,7 +50,7 @@ public class KeyedCipherPropertyEncryptorTest {
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
encryptor = new KeyedCipherPropertyEncryptor(CIPHER_PROVIDER, ENCRYPTION_METHOD, SECRET_KEY);
|
encryptor = new KeyedCipherPropertyEncryptor(SECRET_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -77,18 +70,18 @@ public class KeyedCipherPropertyEncryptorTest {
|
||||||
@Test
|
@Test
|
||||||
public void testDecryptEncryptionException() {
|
public void testDecryptEncryptionException() {
|
||||||
final String encodedProperty = Hex.encodeHexString(PROPERTY.getBytes(DEFAULT_CHARSET));
|
final String encodedProperty = Hex.encodeHexString(PROPERTY.getBytes(DEFAULT_CHARSET));
|
||||||
assertThrows(EncryptionException.class, () -> encryptor.decrypt(encodedProperty));
|
assertThrows(Exception.class, () -> encryptor.decrypt(encodedProperty));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetCipherEncryptionException() {
|
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));
|
assertThrows(EncryptionException.class, () -> encryptor.encrypt(PROPERTY));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEqualsHashCode() {
|
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, equivalentEncryptor);
|
||||||
assertEquals(encryptor.hashCode(), equivalentEncryptor.hashCode());
|
assertEquals(encryptor.hashCode(), equivalentEncryptor.hashCode());
|
||||||
}
|
}
|
||||||
|
@ -96,7 +89,7 @@ public class KeyedCipherPropertyEncryptorTest {
|
||||||
@Test
|
@Test
|
||||||
public void testEqualsHashCodeDifferentSecretKey() {
|
public void testEqualsHashCodeDifferentSecretKey() {
|
||||||
final SecretKey secretKey = new SecretKeySpec(String.class.getSimpleName().getBytes(StandardCharsets.UTF_8), KEY_ALGORITHM);
|
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, differentEncryptor);
|
||||||
assertNotEquals(encryptor.hashCode(), differentEncryptor.hashCode());
|
assertNotEquals(encryptor.hashCode(), differentEncryptor.hashCode());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue