You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by ex...@apache.org on 2021/02/03 14:54:27 UTC

[nifi] branch main updated: NIFI-1355 Implemented new methods in KeyStoreUtils to programmatically-generate certificates, Keystores, and Truststores and return it wrapped in a TLS configuration. Updated TestInvokeHTTP, TestInvokeHttpSSL, TestInvokeHttpTwoWaySSL, and TestListenHTTP to use new Keystore functionality.

This is an automated email from the ASF dual-hosted git repository.

exceptionfactory 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 6e1f737  NIFI-1355  Implemented new methods in KeyStoreUtils to programmatically-generate certificates, Keystores, and Truststores and return it wrapped in a TLS configuration. Updated TestInvokeHTTP, TestInvokeHttpSSL, TestInvokeHttpTwoWaySSL, and TestListenHTTP to use new Keystore functionality.
6e1f737 is described below

commit 6e1f737c53523843b7a3222d0c6dbc2d84e4aa09
Author: mtien <mt...@gmail.com>
AuthorDate: Tue Dec 15 18:08:26 2020 -0800

    NIFI-1355  Implemented new methods in KeyStoreUtils to programmatically-generate certificates, Keystores, and Truststores and return it wrapped in a TLS configuration.
    Updated TestInvokeHTTP, TestInvokeHttpSSL, TestInvokeHttpTwoWaySSL, and TestListenHTTP to use new Keystore functionality.
    
    NIFI-1355 Refactored and removed unnecessary unit tests in KeyStoreUtilsGroovyTest.
    
    NIFI-1355 Added a password requirement when creating a new truststore.
    Handled exception when loading a passwordless truststore type of Bouncy Castle PKCS12.
    
    This closes #4801
    
    Signed-off-by: David Handermann <ex...@apache.org>
---
 .../apache/nifi/security/util/KeyStoreUtils.java   | 213 ++++++++++++++++++++-
 .../security/util/KeyStoreUtilsGroovyTest.groovy   |  98 +++++++++-
 .../nifi/security/util/KeyStoreUtilsTest.java      |   5 +-
 .../nifi/processors/standard/TestInvokeHTTP.java   |  71 ++++---
 .../processors/standard/TestInvokeHttpSSL.java     |  91 +++++----
 .../standard/TestInvokeHttpTwoWaySSL.java          |  64 +++++--
 .../nifi/processors/standard/TestListenHTTP.java   | 185 +++++++++++-------
 .../standard/util/TestInvokeHttpCommon.java        |  13 +-
 8 files changed, 563 insertions(+), 177 deletions(-)

diff --git a/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/KeyStoreUtils.java b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/KeyStoreUtils.java
index 704d2ef..1bab318 100644
--- a/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/KeyStoreUtils.java
+++ b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/KeyStoreUtils.java
@@ -19,23 +19,35 @@ package org.apache.nifi.security.util;
 
 import java.io.BufferedInputStream;
 import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.UncheckedIOException;
 import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.GeneralSecurityException;
 import java.security.Key;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
 import java.security.KeyStore;
 import java.security.KeyStoreException;
 import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
 import java.security.Security;
 import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
 import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Objects;
 import javax.net.ssl.KeyManagerFactory;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLParameters;
 import javax.net.ssl.SSLServerSocket;
 import javax.net.ssl.TrustManagerFactory;
+import org.apache.commons.codec.binary.Hex;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.builder.ToStringBuilder;
 import org.bouncycastle.jce.provider.BouncyCastleProvider;
@@ -46,8 +58,24 @@ public class KeyStoreUtils {
     private static final Logger logger = LoggerFactory.getLogger(KeyStoreUtils.class);
 
     public static final String SUN_PROVIDER_NAME = "SUN";
+    private static final String JKS_EXT = ".jks";
+    private static final String PKCS12_EXT = ".p12";
+    private static final String BCFKS_EXT = ".bcfks";
+    private static final String KEY_ALIAS = "nifi-key";
+    private static final String CERT_ALIAS = "nifi-cert";
+    private static final String CERT_DN = "CN=localhost";
+    private static final String KEY_ALGORITHM = "RSA";
+    private static final String SIGNING_ALGORITHM = "SHA256withRSA";
+    private static final int CERT_DURATION_DAYS = 365;
+    private static final int PASSWORD_LENGTH = 16;
+    private static final String TEST_KEYSTORE_PREFIX = "test-keystore-";
+    private static final String TEST_TRUSTSTORE_PREFIX = "test-truststore-";
+
+    private static final String KEYSTORE_ERROR_MSG = "There was an error creating a Keystore.";
+    private static final String TRUSTSTORE_ERROR_MSG = "There was an error creating a Truststore.";
 
     private static final Map<String, String> KEY_STORE_TYPE_PROVIDERS = new HashMap<>();
+    private static final Map<KeystoreType, String> KEY_STORE_EXTENSIONS = new HashMap<>();
 
     static {
         Security.addProvider(new BouncyCastleProvider());
@@ -57,6 +85,12 @@ public class KeyStoreUtils {
         KEY_STORE_TYPE_PROVIDERS.put(KeystoreType.JKS.getType(), SUN_PROVIDER_NAME);
     }
 
+    static {
+        KEY_STORE_EXTENSIONS.put(KeystoreType.JKS, JKS_EXT);
+        KEY_STORE_EXTENSIONS.put(KeystoreType.PKCS12, PKCS12_EXT);
+        KEY_STORE_EXTENSIONS.put(KeystoreType.BCFKS, BCFKS_EXT);
+    }
+
     /**
      * Returns the provider that will be used for the given keyStoreType
      *
@@ -112,6 +146,63 @@ public class KeyStoreUtils {
     }
 
     /**
+     * Creates a temporary default Keystore and Truststore and returns it wrapped in a TLS configuration.
+     *
+     * @return a {@link org.apache.nifi.security.util.TlsConfiguration}
+     */
+    public static TlsConfiguration createTlsConfigAndNewKeystoreTruststore() throws IOException, GeneralSecurityException {
+        return createTlsConfigAndNewKeystoreTruststore(new StandardTlsConfiguration());
+    }
+
+    /**
+     * Creates a temporary Keystore and Truststore and returns it wrapped in a new TLS configuration with the given values.
+     *
+     * @param tlsConfiguration a {@link org.apache.nifi.security.util.TlsConfiguration}
+     * @return a {@link org.apache.nifi.security.util.TlsConfiguration}
+     */
+    public static TlsConfiguration createTlsConfigAndNewKeystoreTruststore(final TlsConfiguration tlsConfiguration) throws IOException, GeneralSecurityException {
+        final Path keyStorePath;
+        final String keystorePassword = StringUtils.isNotBlank(tlsConfiguration.getKeystorePassword()) ? tlsConfiguration.getKeystorePassword() : generatePassword();
+        final KeystoreType keystoreType = tlsConfiguration.getKeystoreType() != null ? tlsConfiguration.getKeystoreType() : KeystoreType.PKCS12;
+        final String keyPassword = StringUtils.isNotBlank(tlsConfiguration.getKeyPassword()) ? tlsConfiguration.getKeyPassword() : keystorePassword;
+        final Path trustStorePath;
+        final String truststorePassword = StringUtils.isNotBlank(tlsConfiguration.getTruststorePassword()) ? tlsConfiguration.getTruststorePassword() : generatePassword();
+        final KeystoreType truststoreType = tlsConfiguration.getTruststoreType() != null ? tlsConfiguration.getTruststoreType() : KeystoreType.PKCS12;
+
+        // Create temporary Keystore file
+        try {
+            keyStorePath = generateTempKeystorePath(keystoreType);
+        } catch (IOException e) {
+            logger.error(KEYSTORE_ERROR_MSG, e);
+            throw new UncheckedIOException(KEYSTORE_ERROR_MSG, e);
+        }
+
+        // Create temporary Truststore file
+        try {
+            trustStorePath = generateTempTruststorePath(truststoreType);
+        } catch (IOException e) {
+            logger.error(TRUSTSTORE_ERROR_MSG, e);
+            throw new UncheckedIOException(TRUSTSTORE_ERROR_MSG, e);
+        }
+
+        // Create X509 Certificate
+        final X509Certificate clientCert = createKeyStoreAndGetX509Certificate(KEY_ALIAS, keystorePassword, keyPassword, keyStorePath.toString(), keystoreType);
+
+        // Create Truststore
+        createTrustStore(clientCert, CERT_ALIAS, truststorePassword, trustStorePath.toString(), truststoreType);
+
+        return new StandardTlsConfiguration(
+                keyStorePath.toString(),
+                keystorePassword,
+                keyPassword,
+                keystoreType,
+                trustStorePath.toString(),
+                truststorePassword,
+                truststoreType,
+                TlsPlatform.getLatestProtocol());
+    }
+
+    /**
      * Returns the {@link KeyManagerFactory} from the provided {@link KeyStore} object, initialized with the key or keystore password.
      *
      * @param keyStore         the loaded keystore
@@ -136,7 +227,7 @@ public class KeyStoreUtils {
     }
 
     /**
-     * Returns the intialized {@link KeyManagerFactory}.
+     * Returns the initialized {@link KeyManagerFactory}.
      *
      * @param tlsConfiguration the TLS configuration
      * @return the initialized key manager factory
@@ -167,7 +258,6 @@ public class KeyStoreUtils {
         return getKeyManagerFactoryFromKeyStore(keyStore, keystorePasswordChars, keyPasswordChars);
     }
 
-
     /**
      * Returns a loaded {@link KeyStore} (acting as a truststore) given the provided configuration values.
      *
@@ -210,7 +300,7 @@ public class KeyStoreUtils {
     }
 
     /**
-     * Returns the intialized {@link TrustManagerFactory}.
+     * Returns the initialized {@link TrustManagerFactory}.
      *
      * @param tlsConfiguration the TLS configuration
      * @return the initialized trust manager factory
@@ -230,6 +320,11 @@ public class KeyStoreUtils {
      * @throws TlsException if there is a problem initializing or reading from the truststore
      */
     public static TrustManagerFactory loadTrustManagerFactory(String truststorePath, String truststorePassword, String truststoreType) throws TlsException {
+        // Bouncy Castle PKCS12 type requires a password
+        if (truststoreType.equalsIgnoreCase(KeystoreType.PKCS12.getType()) && StringUtils.isBlank(truststorePassword)) {
+            throw new IllegalArgumentException("A PKCS12 Truststore Type requires a password");
+        }
+
         // Legacy truststore passwords can be empty
         final char[] truststorePasswordChars = StringUtils.isNotBlank(truststorePassword) ? truststorePassword.toCharArray() : null;
         KeyStore trustStore = loadTrustStore(truststorePath, truststorePasswordChars, truststoreType);
@@ -352,4 +447,116 @@ public class KeyStoreUtils {
                 .append("useClientMode", sslServerSocket.getUseClientMode())
                 .toString();
     }
+
+    /**
+     * Loads the Keystore and returns a X509 Certificate with the given values.
+     *
+     * @param alias            the certificate alias
+     * @param keyStorePassword the keystore password
+     * @param keyPassword      the key password
+     * @param keyStorePath     the keystore path
+     * @param keyStoreType     the keystore type
+     * @return a {@link X509Certificate}
+     */
+    private static X509Certificate createKeyStoreAndGetX509Certificate(
+            final String alias, final String keyStorePassword, final String keyPassword, final String keyStorePath,
+            final KeystoreType keyStoreType) throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException {
+
+        try (final FileOutputStream outputStream = new FileOutputStream(keyStorePath)) {
+            final KeyPair keyPair = KeyPairGenerator.getInstance(KEY_ALGORITHM).generateKeyPair();
+
+            final X509Certificate selfSignedCert = CertificateUtils.generateSelfSignedX509Certificate(
+                    keyPair, CERT_DN, SIGNING_ALGORITHM, CERT_DURATION_DAYS
+            );
+
+            final KeyStore keyStore = loadEmptyKeyStore(keyStoreType);
+            keyStore.setKeyEntry(alias, keyPair.getPrivate(), keyPassword.toCharArray(), new Certificate[]{selfSignedCert});
+            keyStore.store(outputStream, keyStorePassword.toCharArray());
+
+            return selfSignedCert;
+        }
+    }
+
+    /**
+     * Loads the Truststore with the given values.
+     *
+     * @param cert           the certificate
+     * @param alias          the certificate alias
+     * @param password       the truststore password
+     * @param path           the truststore path
+     * @param truststoreType the truststore type
+     */
+    private static void createTrustStore(final X509Certificate cert,
+                                         final String alias, final String password, final String path, final KeystoreType truststoreType)
+            throws KeyStoreException, NoSuchAlgorithmException, CertificateException {
+
+        try (final FileOutputStream outputStream = new FileOutputStream(path)) {
+            final KeyStore trustStore = loadEmptyKeyStore(truststoreType);
+            trustStore.setCertificateEntry(alias, cert);
+            trustStore.store(outputStream, password.toCharArray());
+        } catch (IOException e) {
+            throw new UncheckedIOException(TRUSTSTORE_ERROR_MSG, e);
+        }
+    }
+
+    /**
+     * Generates a temporary keystore file and returns the path.
+     *
+     * @param keystoreType the Keystore type
+     * @return a Path
+     */
+    private static Path generateTempKeystorePath(KeystoreType keystoreType) throws IOException {
+        return Files.createTempFile(TEST_KEYSTORE_PREFIX, getKeystoreExtension(keystoreType));
+    }
+
+    /**
+     * Generates a temporary truststore file and returns the path.
+     *
+     * @param truststoreType the Truststore type
+     * @return a Path
+     */
+    private static Path generateTempTruststorePath(KeystoreType truststoreType) throws IOException {
+        return Files.createTempFile(TEST_TRUSTSTORE_PREFIX, getKeystoreExtension(truststoreType));
+    }
+
+    /**
+     * Loads and returns an empty Keystore backed by the appropriate provider.
+     *
+     * @param keyStoreType the keystore type
+     * @return an empty keystore
+     * @throws KeyStoreException if a keystore of the given type cannot be instantiated
+     */
+    private static KeyStore loadEmptyKeyStore(KeystoreType keyStoreType) throws KeyStoreException, CertificateException, NoSuchAlgorithmException {
+        final KeyStore keyStore;
+        try {
+            keyStore = KeyStore.getInstance(
+                    Objects.requireNonNull(keyStoreType).getType());
+            keyStore.load(null, null);
+            return keyStore;
+        } catch (IOException e) {
+            logger.error("Encountered an error loading keystore: {}", e.getLocalizedMessage());
+            throw new UncheckedIOException("Error loading keystore", e);
+        }
+    }
+
+    /**
+     * Returns the Keystore extension given the Keystore type.
+     *
+     * @param keystoreType the keystore type
+     * @return the keystore extension
+     */
+    private static String getKeystoreExtension(KeystoreType keystoreType) {
+        return KEY_STORE_EXTENSIONS.get(keystoreType);
+    }
+
+    /**
+     * Generates a random Hex-encoded password.
+     *
+     * @return a password as a Hex-encoded String
+     */
+    private static String generatePassword() {
+        final byte[] password = new byte[PASSWORD_LENGTH];
+        new SecureRandom().nextBytes(password);
+        return Hex.encodeHexString(password);
+    }
 }
diff --git a/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/KeyStoreUtilsGroovyTest.groovy b/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/KeyStoreUtilsGroovyTest.groovy
index 7a76348..b3c85f5 100644
--- a/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/KeyStoreUtilsGroovyTest.groovy
+++ b/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/KeyStoreUtilsGroovyTest.groovy
@@ -16,7 +16,9 @@
  */
 package org.apache.nifi.security.util
 
+import org.apache.nifi.util.StringUtils
 import org.junit.After
+import org.junit.AfterClass
 import org.junit.Before
 import org.junit.BeforeClass
 import org.junit.Ignore
@@ -29,6 +31,8 @@ import org.slf4j.LoggerFactory
 import javax.net.ssl.HttpsURLConnection
 import javax.net.ssl.SSLSocket
 import javax.net.ssl.SSLSocketFactory
+import java.nio.file.Files
+import java.nio.file.Paths
 import java.security.KeyStore
 import java.security.cert.Certificate
 
@@ -36,16 +40,29 @@ import java.security.cert.Certificate
 class KeyStoreUtilsGroovyTest extends GroovyTestCase {
     private static final Logger logger = LoggerFactory.getLogger(KeyStoreUtilsGroovyTest.class)
 
-    private static final File KEYSTORE_FILE = new File("src/test/resources/keystore.jks")
-    private static final String KEYSTORE_PASSWORD = "passwordpassword"
-    private static final String KEY_PASSWORD = "keypassword"
-    private static final KeystoreType KEYSTORE_TYPE = KeystoreType.JKS
+    private static final String TEST_KEYSTORE_PASSWORD = "keystorepassword"
+    private static final String TEST_KEY_PASSWORD = "keypassword"
+    private static final String TEST_TRUSTSTORE_PASSWORD = "truststorepassword"
+    private static final KeystoreType DEFAULT_STORE_TYPE = KeystoreType.JKS
+    private static final KeystoreType PKCS12_STORE_TYPE = KeystoreType.PKCS12
+
+    private static TlsConfiguration tlsConfigParam
+    private static TlsConfiguration tlsConfiguration
 
     @BeforeClass
     static void setUpOnce() {
         logger.metaClass.methodMissing = { String name, args ->
             logger.info("[${name?.toUpperCase()}] ${(args as List).join(" ")}")
         }
+
+        tlsConfigParam = new StandardTlsConfiguration(null, TEST_KEYSTORE_PASSWORD, TEST_KEY_PASSWORD, DEFAULT_STORE_TYPE, null, TEST_TRUSTSTORE_PASSWORD, null)
+
+        tlsConfiguration = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore(tlsConfigParam)
+    }
+
+    @AfterClass
+    static void afterClass() throws Exception {
+        deleteKeystoreTruststore(tlsConfiguration);
     }
 
     @Before
@@ -61,9 +78,10 @@ class KeyStoreUtilsGroovyTest extends GroovyTestCase {
     @Test
     void testShouldVerifyKeystoreIsValid() {
         // Arrange
+        final URL ksUrl = getKeystorePathAsUrl(tlsConfiguration.getKeystorePath())
 
         // Act
-        boolean keystoreIsValid = KeyStoreUtils.isStoreValid(KEYSTORE_FILE.toURI().toURL(), KEYSTORE_TYPE, KEYSTORE_PASSWORD.toCharArray())
+        boolean keystoreIsValid = KeyStoreUtils.isStoreValid(ksUrl, DEFAULT_STORE_TYPE, TEST_KEYSTORE_PASSWORD.toCharArray())
 
         // Assert
         assert keystoreIsValid
@@ -72,9 +90,10 @@ class KeyStoreUtilsGroovyTest extends GroovyTestCase {
     @Test
     void testShouldVerifyKeystoreIsNotValid() {
         // Arrange
+        final URL ksUrl = getKeystorePathAsUrl(tlsConfiguration.getKeystorePath())
 
         // Act
-        boolean keystoreIsValid = KeyStoreUtils.isStoreValid(KEYSTORE_FILE.toURI().toURL(), KEYSTORE_TYPE, KEYSTORE_PASSWORD.reverse().toCharArray())
+        boolean keystoreIsValid = KeyStoreUtils.isStoreValid(ksUrl, DEFAULT_STORE_TYPE, TEST_KEYSTORE_PASSWORD.reverse().toCharArray())
 
         // Assert
         assert !keystoreIsValid
@@ -83,9 +102,10 @@ class KeyStoreUtilsGroovyTest extends GroovyTestCase {
     @Test
     void testShouldVerifyKeyPasswordIsValid() {
         // Arrange
+        final URL ksUrl = getKeystorePathAsUrl(tlsConfiguration.getKeystorePath())
 
         // Act
-        boolean keyPasswordIsValid = KeyStoreUtils.isKeyPasswordCorrect(KEYSTORE_FILE.toURI().toURL(), KEYSTORE_TYPE, KEYSTORE_PASSWORD.toCharArray(), KEYSTORE_PASSWORD.toCharArray())
+        boolean keyPasswordIsValid = KeyStoreUtils.isKeyPasswordCorrect(ksUrl, DEFAULT_STORE_TYPE, TEST_KEYSTORE_PASSWORD.toCharArray(), TEST_KEY_PASSWORD.toCharArray())
 
         // Assert
         assert keyPasswordIsValid
@@ -94,9 +114,10 @@ class KeyStoreUtilsGroovyTest extends GroovyTestCase {
     @Test
     void testShouldVerifyKeyPasswordIsNotValid() {
         // Arrange
+        final URL ksUrl = getKeystorePathAsUrl(tlsConfiguration.getKeystorePath())
 
         // Act
-        boolean keyPasswordIsValid = KeyStoreUtils.isKeyPasswordCorrect(KEYSTORE_FILE.toURI().toURL(), KEYSTORE_TYPE, KEYSTORE_PASSWORD.toCharArray(), KEYSTORE_PASSWORD.reverse().toCharArray())
+        boolean keyPasswordIsValid = KeyStoreUtils.isKeyPasswordCorrect(ksUrl, tlsConfiguration.getKeystoreType(), TEST_KEYSTORE_PASSWORD.toCharArray(), TEST_KEY_PASSWORD.reverse().toCharArray())
 
         // Assert
         assert !keyPasswordIsValid
@@ -141,4 +162,65 @@ class KeyStoreUtilsGroovyTest extends GroovyTestCase {
         FileOutputStream fos = new FileOutputStream("/Users/alopresto/Workspace/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/resources/truststore.no-password.jks")
         truststore.store(fos, "".chars)
     }
+
+    @Test
+    void testShouldValidateTlsConfigAndNewKeystoreTruststoreWithParams() {
+        // Assert
+        assert tlsConfiguration.getKeystorePath()
+        assert tlsConfiguration.getTruststorePath()
+        assert tlsConfiguration.getKeystoreType() == DEFAULT_STORE_TYPE
+        assert tlsConfiguration.getTruststoreType() == PKCS12_STORE_TYPE
+        assert tlsConfiguration.getKeystorePassword() == TEST_KEYSTORE_PASSWORD
+    }
+
+    @Test
+    void testShouldValidateTlsConfigAndNewKeystoreTruststoreWithoutParams() {
+        // Act
+        TlsConfiguration testTlsConfig = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore()
+        deleteKeystoreTruststore(testTlsConfig)
+
+        // Assert
+        assert testTlsConfig.getKeystorePath()
+        assert testTlsConfig.getKeyPassword() == testTlsConfig.getKeystorePassword()
+        assert testTlsConfig.getTruststorePassword()
+        assert testTlsConfig.getKeystoreType() == PKCS12_STORE_TYPE
+        assert testTlsConfig.getTruststoreType() == PKCS12_STORE_TYPE
+    }
+
+    @Test
+    void testShouldValidateTlsConfigWithoutKeyPasswordParam() {
+        // Arrange
+        TlsConfiguration testTlsConfigParam = new StandardTlsConfiguration(null, TEST_KEYSTORE_PASSWORD, null, DEFAULT_STORE_TYPE, null, TEST_TRUSTSTORE_PASSWORD, DEFAULT_STORE_TYPE)
+
+        // Act
+        final TlsConfiguration testTlsConfig = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore(testTlsConfigParam)
+        deleteKeystoreTruststore(testTlsConfig)
+
+        // Assert
+        assert testTlsConfig.getKeyPassword() == testTlsConfig.getKeystorePassword()
+    }
+
+    private static URL getKeystorePathAsUrl(String path) {
+        return new File(path).toURI().toURL()
+    }
+
+    private static void deleteKeystoreTruststore(TlsConfiguration tlsConfig) {
+        if (tlsConfig != null) {
+            try {
+                if (StringUtils.isNotBlank(tlsConfig.getKeystorePath())) {
+                    Files.deleteIfExists(Paths.get(tlsConfig.getKeystorePath()))
+                }
+            } catch (IOException e) {
+                throw new IOException("There was an error deleting a keystore: ${e.getMessage()}, ${e}");
+            }
+
+            try {
+                if (StringUtils.isNotBlank(tlsConfig.getTruststorePath())) {
+                    Files.deleteIfExists(Paths.get(tlsConfig.getTruststorePath()))
+                }
+            } catch (IOException e) {
+                throw new IOException("There was an error deleting a truststore: ${e.getMessage()}, ${e}");
+            }
+        }
+    }
 }
diff --git a/nifi-commons/nifi-security-utils/src/test/java/org/apache/nifi/security/util/KeyStoreUtilsTest.java b/nifi-commons/nifi-security-utils/src/test/java/org/apache/nifi/security/util/KeyStoreUtilsTest.java
index 2a8d1fe..bbf8e8e 100644
--- a/nifi-commons/nifi-security-utils/src/test/java/org/apache/nifi/security/util/KeyStoreUtilsTest.java
+++ b/nifi-commons/nifi-security-utils/src/test/java/org/apache/nifi/security/util/KeyStoreUtilsTest.java
@@ -17,9 +17,6 @@
 
 package org.apache.nifi.security.util;
 
-import org.junit.BeforeClass;
-import org.junit.Test;
-
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
@@ -31,6 +28,8 @@ import java.security.NoSuchAlgorithmException;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
+import org.junit.BeforeClass;
+import org.junit.Test;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestInvokeHTTP.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestInvokeHTTP.java
index ee3a62c..0a46bbe 100644
--- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestInvokeHTTP.java
+++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestInvokeHTTP.java
@@ -16,30 +16,27 @@
  */
 package org.apache.nifi.processors.standard;
 
-import static java.nio.charset.StandardCharsets.UTF_8;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.lang.reflect.Field;
 import java.net.URL;
 import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import javax.net.ssl.SSLContext;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.nifi.processors.standard.util.TestInvokeHttpCommon;
-import org.apache.nifi.security.util.KeystoreType;
+import org.apache.nifi.security.util.KeyStoreUtils;
 import org.apache.nifi.security.util.SslContextFactory;
-import org.apache.nifi.security.util.StandardTlsConfiguration;
 import org.apache.nifi.security.util.TlsConfiguration;
 import org.apache.nifi.ssl.SSLContextService;
 import org.apache.nifi.util.MockFlowFile;
 import org.apache.nifi.util.TestRunners;
 import org.eclipse.jetty.server.Request;
 import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.junit.AfterClass;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -48,30 +45,45 @@ import org.mockito.Mockito;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
 public class TestInvokeHTTP extends TestInvokeHttpCommon {
     private static final Logger logger = LoggerFactory.getLogger(TestInvokeHTTP.class);
 
-    private static final String TRUSTSTORE_PATH = "src/test/resources/truststore.jks";
-    private static final String TRUSTSTORE_PASSWORD = "passwordpassword";
-    private static final KeystoreType TRUSTSTORE_TYPE = KeystoreType.JKS;
-    private static final String KEYSTORE_PATH = "src/test/resources/keystore.jks";
-    private static final String KEYSTORE_PASSWORD = "passwordpassword";
-    private static final KeystoreType KEYSTORE_TYPE = KeystoreType.JKS;
-
-    private static final TlsConfiguration TLS_CONFIGURATION = new StandardTlsConfiguration(
-            KEYSTORE_PATH,
-            KEYSTORE_PASSWORD,
-            KEYSTORE_TYPE,
-            TRUSTSTORE_PATH,
-            TRUSTSTORE_PASSWORD,
-            TRUSTSTORE_TYPE
-    );
+    private static TlsConfiguration tlsConfiguration;
 
     @BeforeClass
     public static void beforeClass() throws Exception {
+        // generate new keystore and truststore
+        tlsConfiguration = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore();
         configureServer(null, null);
     }
 
+    @AfterClass
+    public static void afterClass() throws Exception {
+        if (tlsConfiguration != null) {
+            try {
+                if (StringUtils.isNotBlank(tlsConfiguration.getKeystorePath())) {
+                    Files.deleteIfExists(Paths.get(tlsConfiguration.getKeystorePath()));
+                }
+            } catch (IOException e) {
+                throw new IOException("There was an error deleting a keystore: " + e.getMessage(), e);
+            }
+
+            try {
+                if (StringUtils.isNotBlank(tlsConfiguration.getTruststorePath())) {
+                    Files.deleteIfExists(Paths.get(tlsConfiguration.getTruststorePath()));
+                }
+            } catch (IOException e) {
+                throw new IOException("There was an error deleting a truststore: " + e.getMessage(), e);
+            }
+        }
+    }
+
     @Before
     public void before() throws Exception {
         runner = TestRunners.newTestRunner(InvokeHTTP.class);
@@ -82,9 +94,9 @@ public class TestInvokeHTTP extends TestInvokeHttpCommon {
         final String serviceIdentifier = SSLContextService.class.getName();
         final SSLContextService sslContextService = Mockito.mock(SSLContextService.class);
         Mockito.when(sslContextService.getIdentifier()).thenReturn(serviceIdentifier);
-        final SSLContext sslContext = SslContextFactory.createSslContext(TLS_CONFIGURATION);
+        final SSLContext sslContext = SslContextFactory.createSslContext(tlsConfiguration);
         Mockito.when(sslContextService.createContext()).thenReturn(sslContext);
-        Mockito.when(sslContextService.createTlsConfiguration()).thenReturn(TLS_CONFIGURATION);
+        Mockito.when(sslContextService.createTlsConfiguration()).thenReturn(tlsConfiguration);
 
         runner = TestRunners.newTestRunner(InvokeHTTP.class);
 
@@ -140,20 +152,20 @@ public class TestInvokeHTTP extends TestInvokeHttpCommon {
         runner.setProperty(InvokeHTTP.PROP_URL, "http://nifi.apache.org/"); // just a dummy URL no connection goes out
         runner.setProperty(InvokeHTTP.PROP_PROXY_HOST, "${proxy.host}");
 
-        try{
+        try {
             runner.run();
             Assert.fail();
-        } catch (AssertionError e){
+        } catch (AssertionError e) {
             // Expect assertion error when proxy port isn't set but host is.
         }
         runner.setProperty(InvokeHTTP.PROP_PROXY_PORT, "${proxy.port}");
 
         runner.setProperty(InvokeHTTP.PROP_PROXY_USER, "${proxy.username}");
 
-        try{
+        try {
             runner.run();
             Assert.fail();
-        } catch (AssertionError e){
+        } catch (AssertionError e) {
             // Expect assertion error when proxy password isn't set but host is.
         }
         runner.setProperty(InvokeHTTP.PROP_PROXY_PASSWORD, "${proxy.password}");
@@ -433,5 +445,4 @@ public class TestInvokeHTTP extends TestInvokeHttpCommon {
             }
         }
     }
-
 }
diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestInvokeHttpSSL.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestInvokeHttpSSL.java
index 87c10be..67c6e77 100644
--- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestInvokeHttpSSL.java
+++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestInvokeHttpSSL.java
@@ -17,63 +17,76 @@
 
 package org.apache.nifi.processors.standard;
 
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import javax.net.ssl.SSLContext;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.nifi.processors.standard.util.TestInvokeHttpCommon;
 import org.apache.nifi.security.util.ClientAuth;
-import org.apache.nifi.security.util.KeystoreType;
+import org.apache.nifi.security.util.KeyStoreUtils;
 import org.apache.nifi.security.util.SslContextFactory;
 import org.apache.nifi.security.util.StandardTlsConfiguration;
 import org.apache.nifi.security.util.TlsConfiguration;
-
 import org.apache.nifi.ssl.SSLContextService;
 import org.apache.nifi.util.TestRunners;
+import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.mockito.Mockito;
 
-import javax.net.ssl.SSLContext;
-
 /**
  * Executes the same tests as TestInvokeHttp but with one-way SSL enabled.  The Jetty server created for these tests
  * will not require client certificates and the client will not use keystore properties in the SSLContextService.
  */
 public class TestInvokeHttpSSL extends TestInvokeHttpCommon {
 
-    protected static final String TRUSTSTORE_PATH = "src/test/resources/truststore.no-password.jks";
-    protected static final String TRUSTSTORE_PASSWORD = "";
-    protected static final KeystoreType TRUSTSTORE_TYPE = KeystoreType.JKS;
-
-    private static final String KEYSTORE_PATH = "src/test/resources/keystore.jks";
-    private static final String KEYSTORE_PASSWORD = "passwordpassword";
-    private static final KeystoreType KEYSTORE_TYPE = KeystoreType.JKS;
-
     private static final String HTTP_CONNECT_TIMEOUT = "30 s";
     private static final String HTTP_READ_TIMEOUT = "30 s";
 
-    protected static final TlsConfiguration SERVER_CONFIGURATION = new StandardTlsConfiguration(
-            KEYSTORE_PATH,
-            KEYSTORE_PASSWORD,
-            KEYSTORE_TYPE,
-            TRUSTSTORE_PATH,
-            TRUSTSTORE_PASSWORD,
-            TRUSTSTORE_TYPE
-    );
-
-    protected static SSLContext clientSslContext;
-
-    private static final TlsConfiguration CLIENT_CONFIGURATION = new StandardTlsConfiguration(
-            null,
-            null,
-            null,
-            TRUSTSTORE_PATH,
-            TRUSTSTORE_PASSWORD,
-            TRUSTSTORE_TYPE
-    );
+    protected static TlsConfiguration serverConfiguration;
+
+    private static SSLContext truststoreSslContext;
+    private static TlsConfiguration truststoreConfiguration;
 
     @BeforeClass
     public static void beforeClass() throws Exception {
-        final SSLContext serverContext = SslContextFactory.createSslContext(SERVER_CONFIGURATION);
+        // generate new keystore and truststore
+        serverConfiguration = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore();
+
+        truststoreConfiguration = new StandardTlsConfiguration(
+                null,
+                null,
+                null,
+                serverConfiguration.getTruststorePath(),
+                serverConfiguration.getTruststorePassword(),
+                serverConfiguration.getTruststoreType()
+        );
+
+        final SSLContext serverContext = SslContextFactory.createSslContext(serverConfiguration);
         configureServer(serverContext, ClientAuth.NONE);
-        clientSslContext = SslContextFactory.createSslContext(CLIENT_CONFIGURATION);
+        truststoreSslContext = SslContextFactory.createSslContext(truststoreConfiguration);
+    }
+
+    @AfterClass
+    public static void afterClass() throws Exception {
+        if (serverConfiguration != null) {
+            try {
+                if (StringUtils.isNotBlank(serverConfiguration.getKeystorePath())) {
+                    Files.deleteIfExists(Paths.get(serverConfiguration.getKeystorePath()));
+                }
+            } catch (IOException e) {
+                throw new IOException("There was an error deleting a keystore: " + e.getMessage(), e);
+            }
+
+            try {
+                if (StringUtils.isNotBlank(serverConfiguration.getTruststorePath())) {
+                    Files.deleteIfExists(Paths.get(serverConfiguration.getTruststorePath()));
+                }
+            } catch (IOException e) {
+                throw new IOException("There was an error deleting a truststore: " + e.getMessage(), e);
+            }
+        }
     }
 
     @Before
@@ -82,8 +95,8 @@ public class TestInvokeHttpSSL extends TestInvokeHttpCommon {
         final String serviceIdentifier = SSLContextService.class.getName();
 
         Mockito.when(sslContextService.getIdentifier()).thenReturn(serviceIdentifier);
-        Mockito.when(sslContextService.createContext()).thenReturn(clientSslContext);
-        Mockito.when(sslContextService.createTlsConfiguration()).thenReturn(CLIENT_CONFIGURATION);
+        Mockito.when(sslContextService.createContext()).thenReturn(getClientSslContext());
+        Mockito.when(sslContextService.createTlsConfiguration()).thenReturn(getClientConfiguration());
 
         runner = TestRunners.newTestRunner(InvokeHTTP.class);
         runner.addControllerService(serviceIdentifier, sslContextService);
@@ -93,4 +106,12 @@ public class TestInvokeHttpSSL extends TestInvokeHttpCommon {
         runner.setProperty(InvokeHTTP.PROP_CONNECT_TIMEOUT, HTTP_CONNECT_TIMEOUT);
         runner.setProperty(InvokeHTTP.PROP_READ_TIMEOUT, HTTP_READ_TIMEOUT);
     }
+
+    protected SSLContext getClientSslContext() {
+        return truststoreSslContext;
+    }
+
+    protected TlsConfiguration getClientConfiguration() {
+        return truststoreConfiguration;
+    }
 }
diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestInvokeHttpTwoWaySSL.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestInvokeHttpTwoWaySSL.java
index 6c3d71d..a068437 100644
--- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestInvokeHttpTwoWaySSL.java
+++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestInvokeHttpTwoWaySSL.java
@@ -17,15 +17,18 @@
 
 package org.apache.nifi.processors.standard;
 
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import javax.net.ssl.SSLContext;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.nifi.security.util.ClientAuth;
-import org.apache.nifi.security.util.KeystoreType;
+import org.apache.nifi.security.util.KeyStoreUtils;
 import org.apache.nifi.security.util.SslContextFactory;
-import org.apache.nifi.security.util.StandardTlsConfiguration;
 import org.apache.nifi.security.util.TlsConfiguration;
+import org.junit.AfterClass;
 import org.junit.BeforeClass;
 
-import javax.net.ssl.SSLContext;
-
 /**
  * This is probably overkill but in keeping with the same pattern as the TestInvokeHttp and TestInvokeHttpSSL class,
  * we will execute the same tests using two-way SSL. The Jetty server created for these tests will require client
@@ -33,23 +36,48 @@ import javax.net.ssl.SSLContext;
  */
 public class TestInvokeHttpTwoWaySSL extends TestInvokeHttpSSL {
 
-    private static final String CLIENT_KEYSTORE_PATH = "src/test/resources/client-keystore.p12";
-    private static final String CLIENT_KEYSTORE_PASSWORD = "passwordpassword";
-    private static final KeystoreType CLIENT_KEYSTORE_TYPE = KeystoreType.PKCS12;
-
-    private static final TlsConfiguration CLIENT_CONFIGURATION = new StandardTlsConfiguration(
-            CLIENT_KEYSTORE_PATH,
-            CLIENT_KEYSTORE_PASSWORD,
-            CLIENT_KEYSTORE_TYPE,
-            TRUSTSTORE_PATH,
-            TRUSTSTORE_PASSWORD,
-            TRUSTSTORE_TYPE
-    );
+    private static TlsConfiguration serverConfig;
+    private static SSLContext clientSslContext;
 
     @BeforeClass
     public static void beforeClass() throws Exception {
-        final SSLContext serverContext = SslContextFactory.createSslContext(SERVER_CONFIGURATION);
+        // generate new keystore and truststore
+        serverConfig = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore();
+
+        final SSLContext serverContext = SslContextFactory.createSslContext(serverConfig);
         configureServer(serverContext, ClientAuth.REQUIRED);
-        clientSslContext = SslContextFactory.createSslContext(CLIENT_CONFIGURATION);
+        clientSslContext = SslContextFactory.createSslContext(serverConfig);
     }
+
+    @AfterClass
+    public static void afterClass() throws Exception {
+        if (serverConfig != null) {
+            try {
+                if (StringUtils.isNotBlank(serverConfig.getKeystorePath())) {
+                    Files.deleteIfExists(Paths.get(serverConfig.getKeystorePath()));
+                }
+            } catch (IOException e) {
+                throw new IOException("There was an error deleting a keystore: " + e.getMessage(), e);
+            }
+
+            try {
+                if (StringUtils.isNotBlank(serverConfig.getTruststorePath())) {
+                    Files.deleteIfExists(Paths.get(serverConfig.getTruststorePath()));
+                }
+            } catch (IOException e) {
+                throw new IOException("There was an error deleting a truststore: " + e.getMessage(), e);
+            }
+        }
+    }
+
+    @Override
+    protected SSLContext getClientSslContext() {
+        return clientSslContext;
+    }
+
+    @Override
+    protected TlsConfiguration getClientConfiguration() {
+        return serverConfig;
+    }
+
 }
diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestListenHTTP.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestListenHTTP.java
index 7fc620a..09caa5c 100644
--- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestListenHTTP.java
+++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestListenHTTP.java
@@ -16,23 +16,23 @@
  */
 package org.apache.nifi.processors.standard;
 
-import static org.apache.nifi.processors.standard.ListenHTTP.RELATIONSHIP_SUCCESS;
-import static org.junit.Assert.assertThrows;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
 import com.google.common.base.Charsets;
 import com.google.common.base.Optional;
 import com.google.common.collect.Iterables;
-import com.google.common.io.Files;
 import java.io.DataOutputStream;
 import java.io.File;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.net.HttpURLConnection;
 import java.net.InetSocketAddress;
 import java.net.Socket;
 import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.GeneralSecurityException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Random;
 import java.util.concurrent.TimeUnit;
@@ -51,22 +51,24 @@ import okhttp3.OkHttpClient;
 import okhttp3.Request;
 import okhttp3.RequestBody;
 import okhttp3.Response;
-
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.nifi.processor.ProcessContext;
 import org.apache.nifi.processor.ProcessSessionFactory;
 import org.apache.nifi.remote.io.socket.NetworkUtils;
 import org.apache.nifi.reporting.InitializationException;
+import org.apache.nifi.security.util.KeyStoreUtils;
 import org.apache.nifi.security.util.KeystoreType;
 import org.apache.nifi.security.util.SslContextFactory;
 import org.apache.nifi.security.util.StandardTlsConfiguration;
 import org.apache.nifi.security.util.TlsConfiguration;
-import org.apache.nifi.security.util.TlsException;
 import org.apache.nifi.ssl.RestrictedSSLContextService;
 import org.apache.nifi.ssl.SSLContextService;
 import org.apache.nifi.util.MockFlowFile;
 import org.apache.nifi.util.TestRunner;
 import org.apache.nifi.util.TestRunners;
 import org.junit.After;
+import org.junit.AfterClass;
 import org.junit.Assert;
 import org.junit.Assume;
 import org.junit.Before;
@@ -74,6 +76,11 @@ import org.junit.BeforeClass;
 import org.junit.Test;
 import org.mockito.Mockito;
 
+import static org.apache.nifi.processors.standard.ListenHTTP.RELATIONSHIP_SUCCESS;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.fail;
+
 public class TestListenHTTP {
 
     private static final String SSL_CONTEXT_SERVICE_IDENTIFIER = "ssl-context";
@@ -105,39 +112,12 @@ public class TestListenHTTP {
     private static final int SOCKET_CONNECT_TIMEOUT = 100;
     private static final long SERVER_START_TIMEOUT = 1200000;
 
-    private static final TlsConfiguration SERVER_CONFIGURATION = new StandardTlsConfiguration(
-            KEYSTORE,
-            KEYSTORE_PASSWORD,
-            KEYSTORE_PASSWORD,
-            KEYSTORE_TYPE,
-            TRUSTSTORE,
-            TRUSTSTORE_PASSWORD,
-            TRUSTSTORE_TYPE,
-            TLS_1_2
-    );
-    private static final TlsConfiguration SERVER_TLS_1_3_CONFIGURATION = new StandardTlsConfiguration(
-            KEYSTORE,
-            KEYSTORE_PASSWORD,
-            KEYSTORE_PASSWORD,
-            KEYSTORE_TYPE,
-            TRUSTSTORE,
-            TRUSTSTORE_PASSWORD,
-            TRUSTSTORE_TYPE,
-            TLS_1_3
-    );
-    private static final TlsConfiguration SERVER_NO_TRUSTSTORE_CONFIGURATION = new StandardTlsConfiguration(
-            KEYSTORE,
-            KEYSTORE_PASSWORD,
-            KEYSTORE_PASSWORD,
-            KEYSTORE_TYPE,
-            null,
-            null,
-            null,
-            TLS_1_2
-    );
+    private static TlsConfiguration tlsConfiguration;
+    private static TlsConfiguration serverConfiguration;
+    private static TlsConfiguration serverTls_1_3_Configuration;
+    private static TlsConfiguration serverNoTruststoreConfiguration;
     private static SSLContext serverKeyStoreSslContext;
     private static SSLContext serverKeyStoreNoTrustStoreSslContext;
-
     private static SSLContext keyStoreSslContext;
     private static SSLContext trustStoreSslContext;
 
@@ -147,29 +127,84 @@ public class TestListenHTTP {
     private int availablePort;
 
     @BeforeClass
-    public static void setUpSuite() throws TlsException {
-        serverKeyStoreSslContext = SslContextFactory.createSslContext(SERVER_CONFIGURATION);
-        final TrustManager[] defaultTrustManagers = SslContextFactory.getTrustManagers(SERVER_NO_TRUSTSTORE_CONFIGURATION);
-        serverKeyStoreNoTrustStoreSslContext = SslContextFactory.createSslContext(SERVER_NO_TRUSTSTORE_CONFIGURATION, defaultTrustManagers);
+    public static void setUpSuite() throws GeneralSecurityException, IOException {
+        // generate new keystore and truststore
+        tlsConfiguration = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore();
+
+        serverConfiguration = new StandardTlsConfiguration(
+                tlsConfiguration.getKeystorePath(),
+                tlsConfiguration.getKeystorePassword(),
+                tlsConfiguration.getKeyPassword(),
+                tlsConfiguration.getKeystoreType(),
+                tlsConfiguration.getTruststorePath(),
+                tlsConfiguration.getTruststorePassword(),
+                tlsConfiguration.getTruststoreType(),
+                TLS_1_2
+        );
+        serverTls_1_3_Configuration = new StandardTlsConfiguration(
+                tlsConfiguration.getKeystorePath(),
+                tlsConfiguration.getKeystorePassword(),
+                tlsConfiguration.getKeyPassword(),
+                tlsConfiguration.getKeystoreType(),
+                tlsConfiguration.getTruststorePath(),
+                tlsConfiguration.getTruststorePassword(),
+                tlsConfiguration.getTruststoreType(),
+                TLS_1_3
+        );
+        serverNoTruststoreConfiguration = new StandardTlsConfiguration(
+                tlsConfiguration.getKeystorePath(),
+                tlsConfiguration.getKeystorePassword(),
+                tlsConfiguration.getKeyPassword(),
+                tlsConfiguration.getKeystoreType(),
+                null,
+                null,
+                null,
+                TLS_1_2
+        );
+
+        serverKeyStoreSslContext = SslContextFactory.createSslContext(serverConfiguration);
+        final TrustManager[] defaultTrustManagers = SslContextFactory.getTrustManagers(serverNoTruststoreConfiguration);
+        serverKeyStoreNoTrustStoreSslContext = SslContextFactory.createSslContext(serverNoTruststoreConfiguration, defaultTrustManagers);
 
         keyStoreSslContext = SslContextFactory.createSslContext(new StandardTlsConfiguration(
-                CLIENT_KEYSTORE,
-                KEYSTORE_PASSWORD,
-                CLIENT_KEYSTORE_TYPE,
-                TRUSTSTORE,
-                TRUSTSTORE_PASSWORD,
-                TRUSTSTORE_TYPE)
+                tlsConfiguration.getKeystorePath(),
+                tlsConfiguration.getKeystorePassword(),
+                tlsConfiguration.getKeystoreType(),
+                tlsConfiguration.getTruststorePath(),
+                tlsConfiguration.getTruststorePassword(),
+                tlsConfiguration.getTruststoreType())
         );
         trustStoreSslContext = SslContextFactory.createSslContext(new StandardTlsConfiguration(
                 null,
                 null,
                 null,
-                TRUSTSTORE,
-                TRUSTSTORE_PASSWORD,
-                TRUSTSTORE_TYPE)
+                tlsConfiguration.getTruststorePath(),
+                tlsConfiguration.getTruststorePassword(),
+                tlsConfiguration.getTruststoreType())
         );
     }
 
+    @AfterClass
+    public static void afterClass() throws Exception {
+        if (tlsConfiguration != null) {
+            try {
+                if (StringUtils.isNotBlank(tlsConfiguration.getKeystorePath())) {
+                    Files.deleteIfExists(Paths.get(tlsConfiguration.getKeystorePath()));
+                }
+            } catch (IOException e) {
+                throw new IOException("There was an error deleting a keystore: " + e.getMessage(), e);
+            }
+
+            try {
+                if (StringUtils.isNotBlank(tlsConfiguration.getTruststorePath())) {
+                    Files.deleteIfExists(Paths.get(tlsConfiguration.getTruststorePath()));
+                }
+            } catch (IOException e) {
+                throw new IOException("There was an error deleting a truststore: " + e.getMessage(), e);
+            }
+        }
+    }
+
     @Before
     public void setup() throws IOException {
         proc = new ListenHTTP();
@@ -223,7 +258,7 @@ public class TestListenHTTP {
 
     @Test
     public void testSecurePOSTRequestsReceivedWithoutEL() throws Exception {
-        configureProcessorSslContextService(ListenHTTP.ClientAuthentication.AUTO, SERVER_NO_TRUSTSTORE_CONFIGURATION);
+        configureProcessorSslContextService(ListenHTTP.ClientAuthentication.AUTO, serverNoTruststoreConfiguration);
 
         runner.setProperty(ListenHTTP.PORT, Integer.toString(availablePort));
         runner.setProperty(ListenHTTP.BASE_PATH, HTTP_BASE_PATH);
@@ -234,7 +269,7 @@ public class TestListenHTTP {
 
     @Test
     public void testSecurePOSTRequestsReturnCodeReceivedWithoutEL() throws Exception {
-        configureProcessorSslContextService(ListenHTTP.ClientAuthentication.AUTO, SERVER_NO_TRUSTSTORE_CONFIGURATION);
+        configureProcessorSslContextService(ListenHTTP.ClientAuthentication.AUTO, serverNoTruststoreConfiguration);
 
         runner.setProperty(ListenHTTP.PORT, Integer.toString(availablePort));
         runner.setProperty(ListenHTTP.BASE_PATH, HTTP_BASE_PATH);
@@ -246,7 +281,7 @@ public class TestListenHTTP {
 
     @Test
     public void testSecurePOSTRequestsReceivedWithEL() throws Exception {
-        configureProcessorSslContextService(ListenHTTP.ClientAuthentication.AUTO, SERVER_NO_TRUSTSTORE_CONFIGURATION);
+        configureProcessorSslContextService(ListenHTTP.ClientAuthentication.AUTO, serverNoTruststoreConfiguration);
 
         runner.setProperty(ListenHTTP.PORT, HTTP_SERVER_PORT_EL);
         runner.setProperty(ListenHTTP.BASE_PATH, HTTP_SERVER_BASEPATH_EL);
@@ -257,7 +292,7 @@ public class TestListenHTTP {
 
     @Test
     public void testSecurePOSTRequestsReturnCodeReceivedWithEL() throws Exception {
-        configureProcessorSslContextService(ListenHTTP.ClientAuthentication.AUTO, SERVER_NO_TRUSTSTORE_CONFIGURATION);
+        configureProcessorSslContextService(ListenHTTP.ClientAuthentication.AUTO, serverNoTruststoreConfiguration);
 
         runner.setProperty(ListenHTTP.PORT, Integer.toString(availablePort));
         runner.setProperty(ListenHTTP.BASE_PATH, HTTP_BASE_PATH);
@@ -269,7 +304,7 @@ public class TestListenHTTP {
 
     @Test
     public void testSecureTwoWaySslPOSTRequestsReceivedWithoutEL() throws Exception {
-        configureProcessorSslContextService(ListenHTTP.ClientAuthentication.REQUIRED, SERVER_CONFIGURATION);
+        configureProcessorSslContextService(ListenHTTP.ClientAuthentication.REQUIRED, serverConfiguration);
 
         runner.setProperty(ListenHTTP.PORT, Integer.toString(availablePort));
         runner.setProperty(ListenHTTP.BASE_PATH, HTTP_BASE_PATH);
@@ -280,7 +315,7 @@ public class TestListenHTTP {
 
     @Test
     public void testSecureTwoWaySslPOSTRequestsReturnCodeReceivedWithoutEL() throws Exception {
-        configureProcessorSslContextService(ListenHTTP.ClientAuthentication.REQUIRED, SERVER_CONFIGURATION);
+        configureProcessorSslContextService(ListenHTTP.ClientAuthentication.REQUIRED, serverConfiguration);
 
         runner.setProperty(ListenHTTP.PORT, Integer.toString(availablePort));
         runner.setProperty(ListenHTTP.BASE_PATH, HTTP_BASE_PATH);
@@ -292,7 +327,7 @@ public class TestListenHTTP {
 
     @Test
     public void testSecureTwoWaySslPOSTRequestsReceivedWithEL() throws Exception {
-        configureProcessorSslContextService(ListenHTTP.ClientAuthentication.REQUIRED, SERVER_CONFIGURATION);
+        configureProcessorSslContextService(ListenHTTP.ClientAuthentication.REQUIRED, serverConfiguration);
 
         runner.setProperty(ListenHTTP.PORT, HTTP_SERVER_PORT_EL);
         runner.setProperty(ListenHTTP.BASE_PATH, HTTP_SERVER_BASEPATH_EL);
@@ -303,7 +338,7 @@ public class TestListenHTTP {
 
     @Test
     public void testSecureTwoWaySslPOSTRequestsReturnCodeReceivedWithEL() throws Exception {
-        configureProcessorSslContextService(ListenHTTP.ClientAuthentication.REQUIRED, SERVER_CONFIGURATION);
+        configureProcessorSslContextService(ListenHTTP.ClientAuthentication.REQUIRED, serverConfiguration);
 
         runner.setProperty(ListenHTTP.PORT, Integer.toString(availablePort));
         runner.setProperty(ListenHTTP.BASE_PATH, HTTP_BASE_PATH);
@@ -315,12 +350,12 @@ public class TestListenHTTP {
 
     @Test
     public void testSecureServerSupportsCurrentTlsProtocolVersion() throws Exception {
-        configureProcessorSslContextService(ListenHTTP.ClientAuthentication.AUTO, SERVER_NO_TRUSTSTORE_CONFIGURATION);
+        configureProcessorSslContextService(ListenHTTP.ClientAuthentication.AUTO, serverNoTruststoreConfiguration);
         startSecureServer();
 
         final SSLSocketFactory sslSocketFactory = trustStoreSslContext.getSocketFactory();
         final SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(LOCALHOST, availablePort);
-        final String currentProtocol = SERVER_NO_TRUSTSTORE_CONFIGURATION.getProtocol();
+        final String currentProtocol = serverNoTruststoreConfiguration.getProtocol();
         sslSocket.setEnabledProtocols(new String[]{currentProtocol});
 
         sslSocket.startHandshake();
@@ -330,7 +365,7 @@ public class TestListenHTTP {
 
     @Test
     public void testSecureServerTrustStoreConfiguredClientAuthenticationRequired() throws Exception {
-        configureProcessorSslContextService(ListenHTTP.ClientAuthentication.REQUIRED, SERVER_CONFIGURATION);
+        configureProcessorSslContextService(ListenHTTP.ClientAuthentication.REQUIRED, serverConfiguration);
         startSecureServer();
         final HttpsURLConnection connection = getSecureConnection(trustStoreSslContext);
         assertThrows(SSLException.class, connection::getResponseCode);
@@ -342,7 +377,7 @@ public class TestListenHTTP {
 
     @Test
     public void testSecureServerTrustStoreNotConfiguredClientAuthenticationNotRequired() throws Exception {
-        configureProcessorSslContextService(ListenHTTP.ClientAuthentication.AUTO, SERVER_NO_TRUSTSTORE_CONFIGURATION);
+        configureProcessorSslContextService(ListenHTTP.ClientAuthentication.AUTO, serverNoTruststoreConfiguration);
         startSecureServer();
         final HttpsURLConnection connection = getSecureConnection(trustStoreSslContext);
         final int responseCode = connection.getResponseCode();
@@ -355,7 +390,7 @@ public class TestListenHTTP {
         final String protocolMessage = String.format("TLS Protocol required [%s] found [%s]", TLS_1_3, currentProtocol);
         Assume.assumeTrue(protocolMessage, TLS_1_3.equals(currentProtocol));
 
-        configureProcessorSslContextService(ListenHTTP.ClientAuthentication.AUTO, SERVER_TLS_1_3_CONFIGURATION);
+        configureProcessorSslContextService(ListenHTTP.ClientAuthentication.AUTO, serverTls_1_3_Configuration);
 
         runner.setProperty(ListenHTTP.PORT, Integer.toString(availablePort));
         runner.setProperty(ListenHTTP.BASE_PATH, HTTP_BASE_PATH);
@@ -541,11 +576,14 @@ public class TestListenHTTP {
 
         Runnable sendRequestToWebserver = () -> {
             try {
+                File file1 = createTextFile("my-file-text-", ".txt", "Hello", "World");
+                File file2 = createTextFile("my-file-text-", ".txt", "{ \"name\":\"John\", \"age\":30 }");
+
                 MultipartBody multipartBody = new MultipartBody.Builder().setType(MultipartBody.FORM)
                         .addFormDataPart("p1", "v1")
                         .addFormDataPart("p2", "v2")
-                        .addFormDataPart("file1", "my-file-text.txt", RequestBody.create(MediaType.parse("text/plain"), createTextFile("my-file-text.txt", "Hello", "World")))
-                        .addFormDataPart("file2", "my-file-data.json", RequestBody.create(MediaType.parse("application/json"), createTextFile("my-file-text.txt", "{ \"name\":\"John\", \"age\":30 }")))
+                        .addFormDataPart("file1", "my-file-text.txt", RequestBody.create(MediaType.parse("text/plain"), file1))
+                        .addFormDataPart("file2", "my-file-data.json", RequestBody.create(MediaType.parse("application/json"), file2))
                         .addFormDataPart("file3", "my-file-binary.bin", RequestBody.create(MediaType.parse("application/octet-stream"), generateRandomBinaryData(100)))
                         .build();
 
@@ -562,6 +600,8 @@ public class TestListenHTTP {
                         .build();
 
                 try (Response response = client.newCall(request).execute()) {
+                    Files.deleteIfExists(Paths.get(String.valueOf(file1)));
+                    Files.deleteIfExists(Paths.get(String.valueOf(file2)));
                     Assert.assertTrue(String.format("Unexpected code: %s, body: %s", response.code(), response.body().string()), response.isSuccessful());
                 }
             } catch (final Throwable t) {
@@ -625,13 +665,12 @@ public class TestListenHTTP {
         return bytes;
     }
 
-    private File createTextFile(String fileName, String... lines) throws IOException {
-        File file = new File("target/" + fileName);
-        file.deleteOnExit();
-        for (String string : lines) {
-            Files.append(string, file, Charsets.UTF_8);
+    private File createTextFile(String prefix, String extension, String...lines) throws IOException {
+        Path file = Files.createTempFile(prefix, extension);
+        try (FileOutputStream fos = new FileOutputStream(file.toFile())) {
+            IOUtils.writeLines(Arrays.asList(lines), System.lineSeparator(), fos, Charsets.UTF_8);
         }
-        return file;
+        return file.toFile();
     }
 
     protected MockFlowFile findFlowFile(List<MockFlowFile> flowFilesForRelationship, String attributeName, String attributeValue) {
diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/util/TestInvokeHttpCommon.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/util/TestInvokeHttpCommon.java
index b787e25..c20e9ca 100644
--- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/util/TestInvokeHttpCommon.java
+++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/util/TestInvokeHttpCommon.java
@@ -17,12 +17,6 @@
 
 package org.apache.nifi.processors.standard.util;
 
-import static org.apache.commons.codec.binary.Base64.encodeBase64;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.io.UnsupportedEncodingException;
@@ -39,7 +33,6 @@ import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.Part;
-
 import org.apache.nifi.components.PropertyDescriptor;
 import org.apache.nifi.expression.ExpressionLanguageScope;
 import org.apache.nifi.flowfile.attributes.CoreAttributes;
@@ -70,6 +63,12 @@ import org.junit.AfterClass;
 import org.junit.Assert;
 import org.junit.Test;
 
+import static org.apache.commons.codec.binary.Base64.encodeBase64;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
 public abstract class TestInvokeHttpCommon {
 
     protected static Server server;