use of org.apache.nifi.security.util.EncryptionMethod in project nifi by apache.
the class EncryptContent method onTrigger.
@Override
public void onTrigger(final ProcessContext context, final ProcessSession session) {
FlowFile flowFile = session.get();
if (flowFile == null) {
return;
}
final ComponentLog logger = getLogger();
final String method = context.getProperty(ENCRYPTION_ALGORITHM).getValue();
final EncryptionMethod encryptionMethod = EncryptionMethod.valueOf(method);
final String providerName = encryptionMethod.getProvider();
final String algorithm = encryptionMethod.getAlgorithm();
final String password = context.getProperty(PASSWORD).getValue();
final KeyDerivationFunction kdf = KeyDerivationFunction.valueOf(context.getProperty(KEY_DERIVATION_FUNCTION).getValue());
final boolean encrypt = context.getProperty(MODE).getValue().equalsIgnoreCase(ENCRYPT_MODE);
Encryptor encryptor;
StreamCallback callback;
try {
if (isPGPAlgorithm(algorithm)) {
final String filename = flowFile.getAttribute(CoreAttributes.FILENAME.key());
final String publicKeyring = context.getProperty(PUBLIC_KEYRING).getValue();
final String privateKeyring = context.getProperty(PRIVATE_KEYRING).getValue();
if (encrypt && publicKeyring != null) {
final String publicUserId = context.getProperty(PUBLIC_KEY_USERID).getValue();
encryptor = new OpenPGPKeyBasedEncryptor(algorithm, providerName, publicKeyring, publicUserId, null, filename);
} else if (!encrypt && privateKeyring != null) {
final char[] keyringPassphrase = context.getProperty(PRIVATE_KEYRING_PASSPHRASE).evaluateAttributeExpressions().getValue().toCharArray();
encryptor = new OpenPGPKeyBasedEncryptor(algorithm, providerName, privateKeyring, null, keyringPassphrase, filename);
} else {
final char[] passphrase = Normalizer.normalize(password, Normalizer.Form.NFC).toCharArray();
encryptor = new OpenPGPPasswordBasedEncryptor(algorithm, providerName, passphrase, filename);
}
} else if (kdf.equals(KeyDerivationFunction.NONE)) {
// Raw key
final String keyHex = context.getProperty(RAW_KEY_HEX).getValue();
encryptor = new KeyedEncryptor(encryptionMethod, Hex.decodeHex(keyHex.toCharArray()));
} else {
// PBE
final char[] passphrase = Normalizer.normalize(password, Normalizer.Form.NFC).toCharArray();
encryptor = new PasswordBasedEncryptor(encryptionMethod, passphrase, kdf);
}
if (encrypt) {
callback = encryptor.getEncryptionCallback();
} else {
callback = encryptor.getDecryptionCallback();
}
} catch (final Exception e) {
logger.error("Failed to initialize {}cryption algorithm because - ", new Object[] { encrypt ? "en" : "de", e });
session.rollback();
context.yield();
return;
}
try {
final StopWatch stopWatch = new StopWatch(true);
flowFile = session.write(flowFile, callback);
logger.info("successfully {}crypted {}", new Object[] { encrypt ? "en" : "de", flowFile });
session.getProvenanceReporter().modifyContent(flowFile, stopWatch.getElapsed(TimeUnit.MILLISECONDS));
session.transfer(flowFile, REL_SUCCESS);
} catch (final ProcessException e) {
logger.error("Cannot {}crypt {} - ", new Object[] { encrypt ? "en" : "de", flowFile, e });
session.transfer(flowFile, REL_FAILURE);
}
}
use of org.apache.nifi.security.util.EncryptionMethod in project nifi by apache.
the class TestEncryptContent method testRoundTrip.
@Test
public void testRoundTrip() throws IOException {
final TestRunner testRunner = TestRunners.newTestRunner(new EncryptContent());
testRunner.setProperty(EncryptContent.PASSWORD, "short");
testRunner.setProperty(EncryptContent.KEY_DERIVATION_FUNCTION, KeyDerivationFunction.NIFI_LEGACY.name());
// Must be allowed or short password will cause validation errors
testRunner.setProperty(EncryptContent.ALLOW_WEAK_CRYPTO, "allowed");
for (final EncryptionMethod encryptionMethod : EncryptionMethod.values()) {
if (encryptionMethod.isUnlimitedStrength()) {
// cannot test unlimited strength in unit tests because it's not enabled by the JVM by default.
continue;
}
// KeyedCiphers tested in TestEncryptContentGroovy.groovy
if (encryptionMethod.isKeyedCipher()) {
continue;
}
logger.info("Attempting {}", encryptionMethod.name());
testRunner.setProperty(EncryptContent.ENCRYPTION_ALGORITHM, encryptionMethod.name());
testRunner.setProperty(EncryptContent.MODE, EncryptContent.ENCRYPT_MODE);
testRunner.enqueue(Paths.get("src/test/resources/hello.txt"));
testRunner.clearTransferState();
testRunner.run();
testRunner.assertAllFlowFilesTransferred(EncryptContent.REL_SUCCESS, 1);
MockFlowFile flowFile = testRunner.getFlowFilesForRelationship(EncryptContent.REL_SUCCESS).get(0);
testRunner.assertQueueEmpty();
testRunner.setProperty(EncryptContent.MODE, EncryptContent.DECRYPT_MODE);
testRunner.enqueue(flowFile);
testRunner.clearTransferState();
testRunner.run();
testRunner.assertAllFlowFilesTransferred(EncryptContent.REL_SUCCESS, 1);
logger.info("Successfully decrypted {}", encryptionMethod.name());
flowFile = testRunner.getFlowFilesForRelationship(EncryptContent.REL_SUCCESS).get(0);
flowFile.assertContentEquals(new File("src/test/resources/hello.txt"));
}
}
use of org.apache.nifi.security.util.EncryptionMethod in project nifi by apache.
the class AESProvenanceEventEncryptor method decrypt.
/**
* Decrypts the provided byte[] (an encrypted record with accompanying metadata).
*
* @param encryptedRecord the encrypted record in byte[] form
* @param recordId an identifier for this record (eventId, generated, etc.)
* @return the decrypted record
* @throws EncryptionException if there is an issue decrypting this record
*/
@Override
public byte[] decrypt(byte[] encryptedRecord, String recordId) throws EncryptionException {
if (encryptedRecord == null) {
throw new EncryptionException("The encrypted provenance record cannot be missing");
}
EncryptionMetadata metadata;
try {
metadata = extractEncryptionMetadata(encryptedRecord);
} catch (IOException | ClassNotFoundException e) {
final String msg = "Encountered an error reading the encryption metadata: ";
logger.error(msg, e);
throw new EncryptionException(msg, e);
}
if (!SUPPORTED_VERSIONS.contains(metadata.version)) {
throw new EncryptionException("The event was encrypted with version " + metadata.version + " which is not in the list of supported versions " + StringUtils.join(SUPPORTED_VERSIONS, ","));
}
if (keyProvider == null || !keyProvider.keyExists(metadata.keyId) || CryptoUtils.isEmpty(metadata.keyId)) {
throw new EncryptionException("The requested key ID " + metadata.keyId + " is not available");
} else {
try {
logger.debug("Decrypting provenance record " + recordId + " with key ID " + metadata.keyId);
EncryptionMethod method = EncryptionMethod.forAlgorithm(metadata.algorithm);
Cipher cipher = initCipher(method, Cipher.DECRYPT_MODE, keyProvider.getKey(metadata.keyId), metadata.ivBytes);
// Strip the metadata away to get just the cipher bytes
byte[] cipherBytes = extractCipherBytes(encryptedRecord, metadata);
// Perform the actual decryption
byte[] plainBytes = cipher.doFinal(cipherBytes);
logger.debug("Decrypted provenance event record " + recordId + " with key ID " + metadata.keyId);
return plainBytes;
} catch (EncryptionException | BadPaddingException | IllegalBlockSizeException | KeyManagementException e) {
final String msg = "Encountered an exception decrypting provenance record " + recordId;
logger.error(msg, e);
throw new EncryptionException(msg, e);
}
}
}
use of org.apache.nifi.security.util.EncryptionMethod in project nifi by apache.
the class StringEncryptor method decryptPBE.
private byte[] decryptPBE(byte[] cipherBytes) throws DecoderException {
PBECipherProvider pbecp = (PBECipherProvider) cipherProvider;
final EncryptionMethod encryptionMethod = EncryptionMethod.forAlgorithm(algorithm);
// Extract salt
int saltLength = CipherUtility.getSaltLengthForAlgorithm(algorithm);
byte[] salt = new byte[saltLength];
System.arraycopy(cipherBytes, 0, salt, 0, saltLength);
byte[] actualCipherBytes = Arrays.copyOfRange(cipherBytes, saltLength, cipherBytes.length);
// Determine necessary key length
int keyLength = CipherUtility.parseKeyLengthFromAlgorithm(algorithm);
// Generate cipher
try {
Cipher cipher = pbecp.getCipher(encryptionMethod, new String(password.getPassword()), salt, keyLength, false);
// Decrypt the plaintext
return cipher.doFinal(actualCipherBytes);
} catch (Exception e) {
throw new EncryptionException("Could not decrypt sensitive value", e);
}
}
use of org.apache.nifi.security.util.EncryptionMethod in project nifi by apache.
the class StringEncryptor method encryptPBE.
private byte[] encryptPBE(String plaintext) {
PBECipherProvider pbecp = (PBECipherProvider) cipherProvider;
final EncryptionMethod encryptionMethod = EncryptionMethod.forAlgorithm(algorithm);
// Generate salt
byte[] salt;
// NiFi legacy code determined the salt length based on the cipher block size
if (pbecp instanceof NiFiLegacyCipherProvider) {
salt = ((NiFiLegacyCipherProvider) pbecp).generateSalt(encryptionMethod);
} else {
salt = pbecp.generateSalt();
}
// Determine necessary key length
int keyLength = CipherUtility.parseKeyLengthFromAlgorithm(algorithm);
// Generate cipher
try {
Cipher cipher = pbecp.getCipher(encryptionMethod, new String(password.getPassword()), salt, keyLength, true);
// Write IV if necessary (allows for future use of PBKDF2, Bcrypt, or Scrypt)
// byte[] iv = new byte[0];
// if (cipherProvider instanceof RandomIVPBECipherProvider) {
// iv = cipher.getIV();
// }
// Encrypt the plaintext
byte[] cipherBytes = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));
// byte[] rawBytes = CryptoUtils.concatByteArrays(salt, iv, cipherBytes);
return CryptoUtils.concatByteArrays(salt, cipherBytes);
} catch (Exception e) {
throw new EncryptionException("Could not encrypt sensitive value", e);
}
}
Aggregations