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

thenatog 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 5bc8e49c7a NIFI-10755 Refactored SSLContext creation using 
nifi-security-ssl
5bc8e49c7a is described below

commit 5bc8e49c7ab85be8b1e4ec3ff950f463e84f8607
Author: exceptionfactory <[email protected]>
AuthorDate: Thu Nov 3 11:36:08 2022 -0500

    NIFI-10755 Refactored SSLContext creation using nifi-security-ssl
    
    - Added TrustManagerBuilder to nifi-security-ssl
    - Removed SslContextFactory and CertificateUtils from nifi-registry
    - Refactored c2-client-http
    - Refactored minifi-bootstrap
    - Refactored nifi-site-to-site-client
    - Refactored nifi-registry-client
    - Refactored nifi-registry-framework
    - Refactored nifi-toolkit-admin
    - Refactored nifi-toolkit-cli
    
    Signed-off-by: Nathan Gough <[email protected]>
    
    This closes #6618.
---
 c2/c2-client-bundle/c2-client-http/pom.xml         |   5 +
 .../apache/nifi/c2/client/http/C2HttpClient.java   |  61 +-
 minifi/minifi-bootstrap/pom.xml                    |   9 +
 .../ingestors/PullHttpChangeIngestor.java          |  62 +-
 .../ingestors/RestChangeIngestorSSLTest.java       |  90 ++-
 minifi/pom.xml                                     |   5 +
 .../security/ssl/StandardSslContextBuilder.java    |  23 +-
 .../security/ssl/StandardTrustManagerBuilder.java  |  91 +++
 .../nifi/security/ssl/TrustManagerBuilder.java     |  31 +
 nifi-commons/nifi-site-to-site-client/pom.xml      |  10 +
 .../nifi/remote/client/SiteToSiteClient.java       |  71 ++-
 .../nifi/remote/client/http/TestHttpClient.java    |   2 +-
 .../nifi-registry-client/pom.xml                   |   5 +
 .../registry/client/NiFiRegistryClientConfig.java  |  89 ++-
 .../nifi-registry-framework/pom.xml                |   5 +
 .../security/ldap/LdapIdentityProvider.java        |  63 +-
 .../ldap/tenants/LdapUserGroupProvider.java        |  78 ++-
 .../registry/security/util/CertificateUtils.java   | 671 ---------------------
 .../registry/security/util/SslContextFactory.java  | 249 --------
 nifi-toolkit/nifi-toolkit-admin/pom.xml            |   5 +
 .../toolkit/admin/client/NiFiClientFactory.groovy  |  82 ++-
 nifi-toolkit/nifi-toolkit-cli/pom.xml              |   5 +
 .../cli/impl/client/nifi/NiFiClientConfig.java     |  90 ++-
 23 files changed, 480 insertions(+), 1322 deletions(-)

diff --git a/c2/c2-client-bundle/c2-client-http/pom.xml 
b/c2/c2-client-bundle/c2-client-http/pom.xml
index e5bfd786e9..8d106670de 100644
--- a/c2/c2-client-bundle/c2-client-http/pom.xml
+++ b/c2/c2-client-bundle/c2-client-http/pom.xml
@@ -38,6 +38,11 @@ limitations under the License.
             <artifactId>c2-client-base</artifactId>
             <version>1.19.0-SNAPSHOT</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-security-ssl</artifactId>
+            <version>1.19.0-SNAPSHOT</version>
+        </dependency>
         <dependency>
             <groupId>com.squareup.okhttp3</groupId>
             <artifactId>okhttp</artifactId>
diff --git 
a/c2/c2-client-bundle/c2-client-http/src/main/java/org/apache/nifi/c2/client/http/C2HttpClient.java
 
b/c2/c2-client-bundle/c2-client-http/src/main/java/org/apache/nifi/c2/client/http/C2HttpClient.java
index bf9c083a0a..293851c0f5 100644
--- 
a/c2/c2-client-bundle/c2-client-http/src/main/java/org/apache/nifi/c2/client/http/C2HttpClient.java
+++ 
b/c2/c2-client-bundle/c2-client-http/src/main/java/org/apache/nifi/c2/client/http/C2HttpClient.java
@@ -23,15 +23,11 @@ import static okhttp3.RequestBody.create;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.security.KeyStore;
-import java.security.NoSuchAlgorithmException;
 import java.util.Optional;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
-import javax.net.ssl.KeyManagerFactory;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
 import javax.net.ssl.X509TrustManager;
 import okhttp3.MediaType;
 import okhttp3.MultipartBody;
@@ -47,6 +43,9 @@ import org.apache.nifi.c2.protocol.api.C2Heartbeat;
 import org.apache.nifi.c2.protocol.api.C2HeartbeatResponse;
 import org.apache.nifi.c2.protocol.api.C2OperationAck;
 import org.apache.nifi.c2.serializer.C2Serializer;
+import org.apache.nifi.security.ssl.StandardKeyStoreBuilder;
+import org.apache.nifi.security.ssl.StandardSslContextBuilder;
+import org.apache.nifi.security.ssl.StandardTrustManagerBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -195,50 +194,40 @@ public class C2HttpClient implements C2Client {
         final String keystoreLocation = clientConfig.getKeystoreFilename();
         final String keystoreType = clientConfig.getKeystoreType();
         final String keystorePass = clientConfig.getKeystorePass();
-
         assertKeystorePropertiesSet(keystoreLocation, keystorePass, 
keystoreType);
 
-        // prepare the keystore
-        final KeyStore keyStore = KeyStore.getInstance(keystoreType);
-
-        try (FileInputStream keyStoreStream = new 
FileInputStream(keystoreLocation)) {
-            keyStore.load(keyStoreStream, keystorePass.toCharArray());
+        final KeyStore keyStore;
+        try (final FileInputStream keyStoreStream = new 
FileInputStream(keystoreLocation)) {
+            keyStore = new StandardKeyStoreBuilder()
+                    .type(keystoreType)
+                    .inputStream(keyStoreStream)
+                    .password(keystorePass.toCharArray())
+                    .build();
         }
 
-        final KeyManagerFactory keyManagerFactory = 
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
-        keyManagerFactory.init(keyStore, keystorePass.toCharArray());
-
-        // load truststore
         final String truststoreLocation = clientConfig.getTruststoreFilename();
         final String truststorePass = clientConfig.getTruststorePass();
         final String truststoreType = clientConfig.getTruststoreType();
         assertTruststorePropertiesSet(truststoreLocation, truststorePass, 
truststoreType);
 
-        KeyStore truststore = KeyStore.getInstance(truststoreType);
-        final TrustManagerFactory trustManagerFactory = 
TrustManagerFactory.getInstance("X509");
-        truststore.load(new FileInputStream(truststoreLocation), 
truststorePass.toCharArray());
-        trustManagerFactory.init(truststore);
-
-        final X509TrustManager x509TrustManager;
-        TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
-        if (trustManagers[0] != null) {
-            x509TrustManager = (X509TrustManager) trustManagers[0];
-        } else {
-            throw new IllegalStateException("List of trust managers is null");
-        }
-
-        SSLContext tempSslContext;
-        try {
-            tempSslContext = SSLContext.getInstance("TLS");
-        } catch (NoSuchAlgorithmException e) {
-            throw new IllegalStateException("SSLContext creation failed", e);
+        final KeyStore truststore;
+        try (final FileInputStream trustStoreStream = new 
FileInputStream(truststoreLocation)) {
+            truststore = new StandardKeyStoreBuilder()
+                    .type(truststoreType)
+                    .inputStream(trustStoreStream)
+                    .password(truststorePass.toCharArray())
+                    .build();
         }
 
-        final SSLContext sslContext = tempSslContext;
-        sslContext.init(keyManagerFactory.getKeyManagers(), 
trustManagerFactory.getTrustManagers(), null);
-
+        final X509TrustManager trustManager = new 
StandardTrustManagerBuilder().trustStore(truststore).build();
+        final SSLContext sslContext = new StandardSslContextBuilder()
+                .keyStore(keyStore)
+                .keyPassword(keystorePass.toCharArray())
+                .trustStore(truststore)
+                .build();
         final SSLSocketFactory sslSocketFactory = 
sslContext.getSocketFactory();
-        okHttpClientBuilder.sslSocketFactory(sslSocketFactory, 
x509TrustManager);
+
+        okHttpClientBuilder.sslSocketFactory(sslSocketFactory, trustManager);
     }
 
     private void assertKeystorePropertiesSet(String location, String password, 
String type) {
diff --git a/minifi/minifi-bootstrap/pom.xml b/minifi/minifi-bootstrap/pom.xml
index c125a2e160..bca0fe444c 100644
--- a/minifi/minifi-bootstrap/pom.xml
+++ b/minifi/minifi-bootstrap/pom.xml
@@ -69,6 +69,10 @@ limitations under the License.
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-xml-processing</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-security-ssl</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-properties</artifactId>
@@ -113,6 +117,11 @@ limitations under the License.
             <groupId>com.fasterxml.jackson.core</groupId>
             <artifactId>jackson-databind</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-security-utils</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
 
diff --git 
a/minifi/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/configuration/ingestors/PullHttpChangeIngestor.java
 
b/minifi/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/configuration/ingestors/PullHttpChangeIngestor.java
index 02e4bac6eb..14000d9e6b 100644
--- 
a/minifi/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/configuration/ingestors/PullHttpChangeIngestor.java
+++ 
b/minifi/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/configuration/ingestors/PullHttpChangeIngestor.java
@@ -26,7 +26,6 @@ import java.net.InetSocketAddress;
 import java.net.Proxy;
 import java.nio.ByteBuffer;
 import java.security.KeyStore;
-import java.security.NoSuchAlgorithmException;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
@@ -34,11 +33,8 @@ import java.util.Properties;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.Supplier;
-import javax.net.ssl.KeyManagerFactory;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
 import javax.net.ssl.X509TrustManager;
 import okhttp3.Credentials;
 import okhttp3.HttpUrl;
@@ -52,6 +48,9 @@ import 
org.apache.nifi.minifi.bootstrap.configuration.differentiators.Differenti
 import 
org.apache.nifi.minifi.bootstrap.configuration.differentiators.WholeConfigDifferentiator;
 import org.apache.nifi.minifi.bootstrap.util.ConfigTransformer;
 import org.apache.nifi.minifi.commons.schema.common.StringUtil;
+import org.apache.nifi.security.ssl.StandardKeyStoreBuilder;
+import org.apache.nifi.security.ssl.StandardSslContextBuilder;
+import org.apache.nifi.security.ssl.StandardTrustManagerBuilder;
 import org.slf4j.LoggerFactory;
 
 
@@ -273,51 +272,40 @@ public class PullHttpChangeIngestor extends 
AbstractPullChangeIngestor {
         final String keystoreLocation = 
properties.getProperty(KEYSTORE_LOCATION_KEY);
         final String keystorePass = 
properties.getProperty(KEYSTORE_PASSWORD_KEY);
         final String keystoreType = properties.getProperty(KEYSTORE_TYPE_KEY);
-
         assertKeystorePropertiesSet(keystoreLocation, keystorePass, 
keystoreType);
 
-        // prepare the keystore
-        final KeyStore keyStore = KeyStore.getInstance(keystoreType);
-
-        try (FileInputStream keyStoreStream = new 
FileInputStream(keystoreLocation)) {
-            keyStore.load(keyStoreStream, keystorePass.toCharArray());
+        final KeyStore keyStore;
+        try (final FileInputStream keyStoreStream = new 
FileInputStream(keystoreLocation)) {
+            keyStore = new StandardKeyStoreBuilder()
+                    .type(keystoreType)
+                    .inputStream(keyStoreStream)
+                    .password(keystorePass.toCharArray())
+                    .build();
         }
 
-        final KeyManagerFactory keyManagerFactory = 
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
-        keyManagerFactory.init(keyStore, keystorePass.toCharArray());
-
-        // load truststore
         final String truststoreLocation = 
properties.getProperty(TRUSTSTORE_LOCATION_KEY);
         final String truststorePass = 
properties.getProperty(TRUSTSTORE_PASSWORD_KEY);
         final String truststoreType = 
properties.getProperty(TRUSTSTORE_TYPE_KEY);
         assertTruststorePropertiesSet(truststoreLocation, truststorePass, 
truststoreType);
 
-        KeyStore truststore = KeyStore.getInstance(truststoreType);
-        final TrustManagerFactory trustManagerFactory = 
TrustManagerFactory.getInstance("X509");
-        truststore.load(new FileInputStream(truststoreLocation), 
truststorePass.toCharArray());
-        trustManagerFactory.init(truststore);
-
-        final X509TrustManager x509TrustManager;
-        TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
-        if (trustManagers[0] != null) {
-            x509TrustManager = (X509TrustManager) trustManagers[0];
-        } else {
-            throw new IllegalStateException("List of trust managers is null");
-        }
-
-        SSLContext tempSslContext;
-        try {
-            tempSslContext = SSLContext.getInstance("TLS");
-        } catch (NoSuchAlgorithmException e) {
-            logger.warn("Unable to use 'TLS' for the PullHttpChangeIngestor 
due to NoSuchAlgorithmException. Will attempt to use the default algorithm.", 
e);
-            tempSslContext = SSLContext.getDefault();
+        final KeyStore truststore;
+        try (final FileInputStream trustStoreStream = new 
FileInputStream(truststoreLocation)) {
+            truststore = new StandardKeyStoreBuilder()
+                    .type(truststoreType)
+                    .inputStream(trustStoreStream)
+                    .password(truststorePass.toCharArray())
+                    .build();
         }
 
-        final SSLContext sslContext = tempSslContext;
-        sslContext.init(keyManagerFactory.getKeyManagers(), 
trustManagerFactory.getTrustManagers(), null);
-
+        final X509TrustManager trustManager = new 
StandardTrustManagerBuilder().trustStore(truststore).build();
+        final SSLContext sslContext = new StandardSslContextBuilder()
+                .keyStore(keyStore)
+                .keyPassword(keystorePass.toCharArray())
+                .trustStore(truststore)
+                .build();
         final SSLSocketFactory sslSocketFactory = 
sslContext.getSocketFactory();
-        okHttpClientBuilder.sslSocketFactory(sslSocketFactory, 
x509TrustManager);
+
+        okHttpClientBuilder.sslSocketFactory(sslSocketFactory, trustManager);
     }
 
     private void assertKeystorePropertiesSet(String location, String password, 
String type) {
diff --git 
a/minifi/minifi-bootstrap/src/test/java/org/apache/nifi/minifi/bootstrap/configuration/ingestors/RestChangeIngestorSSLTest.java
 
b/minifi/minifi-bootstrap/src/test/java/org/apache/nifi/minifi/bootstrap/configuration/ingestors/RestChangeIngestorSSLTest.java
index 91a56642e9..f58f111677 100644
--- 
a/minifi/minifi-bootstrap/src/test/java/org/apache/nifi/minifi/bootstrap/configuration/ingestors/RestChangeIngestorSSLTest.java
+++ 
b/minifi/minifi-bootstrap/src/test/java/org/apache/nifi/minifi/bootstrap/configuration/ingestors/RestChangeIngestorSSLTest.java
@@ -25,24 +25,21 @@ import 
org.apache.nifi.minifi.bootstrap.configuration.ConfigurationChangeListene
 import 
org.apache.nifi.minifi.bootstrap.configuration.ConfigurationChangeNotifier;
 import org.apache.nifi.minifi.bootstrap.configuration.ListenerHandleResult;
 import 
org.apache.nifi.minifi.bootstrap.configuration.ingestors.common.RestChangeIngestorCommonTest;
+import org.apache.nifi.security.ssl.StandardKeyStoreBuilder;
+import org.apache.nifi.security.ssl.StandardSslContextBuilder;
+import org.apache.nifi.security.ssl.StandardTrustManagerBuilder;
+import org.apache.nifi.security.util.TemporaryKeyStoreBuilder;
+import org.apache.nifi.security.util.TlsConfiguration;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeAll;
 import org.mockito.Mockito;
 
-import javax.net.ssl.KeyManagerFactory;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
 import javax.net.ssl.X509TrustManager;
 import java.io.FileInputStream;
 import java.io.IOException;
-import java.security.KeyManagementException;
 import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.CertificateException;
 import java.util.Collections;
 import java.util.Properties;
 
@@ -52,14 +49,16 @@ import static org.mockito.Mockito.when;
 public class RestChangeIngestorSSLTest extends RestChangeIngestorCommonTest {
 
     @BeforeAll
-    public static void setUpHttps() throws CertificateException, 
NoSuchAlgorithmException, KeyStoreException, IOException, 
UnrecoverableKeyException, KeyManagementException, InterruptedException {
+    public static void setUpHttps() throws IOException, InterruptedException {
+        final TlsConfiguration tlsConfiguration = new 
TemporaryKeyStoreBuilder().trustStoreType("JKS").build();
+
         Properties properties = new Properties();
-        properties.setProperty(RestChangeIngestor.TRUSTSTORE_LOCATION_KEY, 
"./src/test/resources/localhost-ts.jks");
-        properties.setProperty(RestChangeIngestor.TRUSTSTORE_PASSWORD_KEY, 
"localtest");
-        properties.setProperty(RestChangeIngestor.TRUSTSTORE_TYPE_KEY, "JKS");
-        properties.setProperty(RestChangeIngestor.KEYSTORE_LOCATION_KEY, 
"./src/test/resources/localhost-ks.jks");
-        properties.setProperty(RestChangeIngestor.KEYSTORE_PASSWORD_KEY, 
"localtest");
-        properties.setProperty(RestChangeIngestor.KEYSTORE_TYPE_KEY, "JKS");
+        properties.setProperty(RestChangeIngestor.TRUSTSTORE_LOCATION_KEY, 
tlsConfiguration.getTruststorePath());
+        properties.setProperty(RestChangeIngestor.TRUSTSTORE_PASSWORD_KEY, 
tlsConfiguration.getTruststorePassword());
+        properties.setProperty(RestChangeIngestor.TRUSTSTORE_TYPE_KEY, 
tlsConfiguration.getTruststoreType().getType());
+        properties.setProperty(RestChangeIngestor.KEYSTORE_LOCATION_KEY, 
tlsConfiguration.getKeystorePath());
+        properties.setProperty(RestChangeIngestor.KEYSTORE_PASSWORD_KEY, 
tlsConfiguration.getKeystorePassword());
+        properties.setProperty(RestChangeIngestor.KEYSTORE_TYPE_KEY, 
tlsConfiguration.getKeystoreType().getType());
         properties.setProperty(RestChangeIngestor.NEED_CLIENT_AUTH_KEY, 
"false");
         properties.put(PullHttpChangeIngestor.OVERRIDE_SECURITY, "true");
         properties.put(PULL_HTTP_BASE_KEY + ".override.core", "true");
@@ -80,50 +79,33 @@ public class RestChangeIngestorSSLTest extends 
RestChangeIngestorCommonTest {
 
         OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
 
-        final String keystoreLocation = 
"./src/test/resources/localhost-ks.jks";
-        final String keystorePass = "localtest";
-        final String keystoreType = "JKS";
-
-        // prepare the keystore
-        final KeyStore keyStore = KeyStore.getInstance(keystoreType);
-
-        try (FileInputStream keyStoreStream = new 
FileInputStream(keystoreLocation)) {
-            keyStore.load(keyStoreStream, keystorePass.toCharArray());
+        final KeyStore keyStore;
+        try (final FileInputStream keyStoreStream = new 
FileInputStream(tlsConfiguration.getKeystorePath())) {
+            keyStore = new StandardKeyStoreBuilder()
+                    .type(tlsConfiguration.getKeystoreType().getType())
+                    .inputStream(keyStoreStream)
+                    
.password(tlsConfiguration.getKeystorePassword().toCharArray())
+                    .build();
         }
 
-        final KeyManagerFactory keyManagerFactory = 
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
-        keyManagerFactory.init(keyStore, keystorePass.toCharArray());
-
-        // load truststore
-        final String truststoreLocation = 
"./src/test/resources/localhost-ts.jks";
-        final String truststorePass = "localtest";
-        final String truststoreType = "JKS";
-
-        KeyStore truststore = KeyStore.getInstance(truststoreType);
-        final TrustManagerFactory trustManagerFactory = 
TrustManagerFactory.getInstance("X509");
-        truststore.load(new FileInputStream(truststoreLocation), 
truststorePass.toCharArray());
-        trustManagerFactory.init(truststore);
-
-        final X509TrustManager x509TrustManager;
-        TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
-        if (trustManagers[0] != null) {
-            x509TrustManager = (X509TrustManager) trustManagers[0];
-        } else {
-            throw new IllegalStateException("List of trust managers is null");
+        final KeyStore truststore;
+        try (final FileInputStream trustStoreStream = new 
FileInputStream(tlsConfiguration.getTruststorePath())) {
+            truststore = new StandardKeyStoreBuilder()
+                    .type(tlsConfiguration.getTruststoreType().getType())
+                    .inputStream(trustStoreStream)
+                    
.password(tlsConfiguration.getTruststorePassword().toCharArray())
+                    .build();
         }
 
-        SSLContext tempSslContext;
-        try {
-            tempSslContext = SSLContext.getInstance("TLS");
-        } catch (NoSuchAlgorithmException e) {
-            tempSslContext = SSLContext.getDefault();
-        }
-
-        final SSLContext sslContext = tempSslContext;
-        sslContext.init(keyManagerFactory.getKeyManagers(), 
trustManagerFactory.getTrustManagers(), null);
-
+        final X509TrustManager trustManager = new 
StandardTrustManagerBuilder().trustStore(truststore).build();
+        final SSLContext sslContext = new StandardSslContextBuilder()
+                .keyStore(keyStore)
+                .keyPassword(tlsConfiguration.getKeyPassword().toCharArray())
+                .trustStore(truststore)
+                .build();
         final SSLSocketFactory sslSocketFactory = 
sslContext.getSocketFactory();
-        clientBuilder.sslSocketFactory(sslSocketFactory, x509TrustManager);
+
+        clientBuilder.sslSocketFactory(sslSocketFactory, trustManager);
 
         Thread.sleep(1000);
         url = restChangeIngestor.getURI().toURL().toString();
diff --git a/minifi/pom.xml b/minifi/pom.xml
index 4ca1fb68d2..83f3ab8cb0 100644
--- a/minifi/pom.xml
+++ b/minifi/pom.xml
@@ -417,6 +417,11 @@ limitations under the License.
                 <artifactId>nifi-security-utils</artifactId>
                 <version>1.19.0-SNAPSHOT</version>
             </dependency>
+            <dependency>
+                <groupId>org.apache.nifi</groupId>
+                <artifactId>nifi-security-ssl</artifactId>
+                <version>1.19.0-SNAPSHOT</version>
+            </dependency>
             <dependency>
                 <groupId>org.apache.nifi</groupId>
                 <artifactId>nifi-xml-processing</artifactId>
diff --git 
a/nifi-commons/nifi-security-ssl/src/main/java/org/apache/nifi/security/ssl/StandardSslContextBuilder.java
 
b/nifi-commons/nifi-security-ssl/src/main/java/org/apache/nifi/security/ssl/StandardSslContextBuilder.java
index 9d82ea9c72..d83c7ebd1b 100644
--- 
a/nifi-commons/nifi-security-ssl/src/main/java/org/apache/nifi/security/ssl/StandardSslContextBuilder.java
+++ 
b/nifi-commons/nifi-security-ssl/src/main/java/org/apache/nifi/security/ssl/StandardSslContextBuilder.java
@@ -20,7 +20,7 @@ import javax.net.ssl.KeyManager;
 import javax.net.ssl.KeyManagerFactory;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
 import java.security.KeyManagementException;
 import java.security.KeyStore;
 import java.security.KeyStoreException;
@@ -116,7 +116,7 @@ public class StandardSslContextBuilder implements 
SslContextBuilder {
             final KeyManagerFactory keyManagerFactory = getKeyManagerFactory();
             try {
                 keyManagerFactory.init(keyStore, keyPassword);
-            } catch (final 
KeyStoreException|NoSuchAlgorithmException|UnrecoverableKeyException e) {
+            } catch (final KeyStoreException | NoSuchAlgorithmException | 
UnrecoverableKeyException e) {
                 throw new BuilderConfigurationException("Key Manager 
initialization failed", e);
             }
             keyManagers = keyManagerFactory.getKeyManagers();
@@ -129,13 +129,8 @@ public class StandardSslContextBuilder implements 
SslContextBuilder {
         if (trustStore == null) {
             trustManagers = null;
         } else {
-            final TrustManagerFactory trustManagerFactory = 
getTrustManagerFactory();
-            try {
-                trustManagerFactory.init(trustStore);
-            } catch (final KeyStoreException e) {
-                throw new BuilderConfigurationException("Trust Manager 
initialization failed", e);
-            }
-            trustManagers = trustManagerFactory.getTrustManagers();
+            final X509TrustManager trustManager = new 
StandardTrustManagerBuilder().trustStore(trustStore).build();
+            trustManagers = new TrustManager[]{trustManager};
         }
         return trustManagers;
     }
@@ -150,16 +145,6 @@ public class StandardSslContextBuilder implements 
SslContextBuilder {
         }
     }
 
-    private TrustManagerFactory getTrustManagerFactory() {
-        final String algorithm = TrustManagerFactory.getDefaultAlgorithm();
-        try {
-            return TrustManagerFactory.getInstance(algorithm);
-        } catch (final NoSuchAlgorithmException e) {
-            final String message = String.format("TrustManagerFactory creation 
failed with algorithm [%s]", algorithm);
-            throw new BuilderConfigurationException(message, e);
-        }
-    }
-
     private SSLContext getSslContext() {
         try {
             return SSLContext.getInstance(protocol);
diff --git 
a/nifi-commons/nifi-security-ssl/src/main/java/org/apache/nifi/security/ssl/StandardTrustManagerBuilder.java
 
b/nifi-commons/nifi-security-ssl/src/main/java/org/apache/nifi/security/ssl/StandardTrustManagerBuilder.java
new file mode 100644
index 0000000000..2aca565156
--- /dev/null
+++ 
b/nifi-commons/nifi-security-ssl/src/main/java/org/apache/nifi/security/ssl/StandardTrustManagerBuilder.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.security.ssl;
+
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * Standard implementation of X.509 Trust Manager Builder
+ */
+public class StandardTrustManagerBuilder implements TrustManagerBuilder {
+    private KeyStore trustStore;
+
+    /**
+     * Build X.509 Trust Manager using configured properties
+     *
+     * @return X.509 Trust Manager
+     */
+    @Override
+    public X509TrustManager build() {
+        final TrustManager[] trustManagers = getTrustManagers();
+        if (trustManagers == null) {
+            throw new BuilderConfigurationException("Trust Managers not found: 
Trust Store required");
+        }
+
+        final Optional<X509TrustManager> configuredTrustManager = 
Arrays.stream(trustManagers)
+                .filter(trustManager -> trustManager instanceof 
X509TrustManager)
+                .map(trustManager -> (X509TrustManager) trustManager)
+                .findFirst();
+
+        return configuredTrustManager.orElseThrow(() -> new 
BuilderConfigurationException("X.509 Trust Manager not found"));
+    }
+
+    /**
+     * Set Trust Store with Certificate Entries
+     *
+     * @param trustStore Trust Store
+     * @return Builder
+     */
+    public StandardTrustManagerBuilder trustStore(final KeyStore trustStore) {
+        this.trustStore = Objects.requireNonNull(trustStore, "Trust Store 
required");
+        return this;
+    }
+
+    private TrustManager[] getTrustManagers() {
+        final TrustManager[] trustManagers;
+        if (trustStore == null) {
+            trustManagers = null;
+        } else {
+            final TrustManagerFactory trustManagerFactory = 
getTrustManagerFactory();
+            try {
+                trustManagerFactory.init(trustStore);
+            } catch (final KeyStoreException e) {
+                throw new BuilderConfigurationException("Trust Manager 
initialization failed", e);
+            }
+            trustManagers = trustManagerFactory.getTrustManagers();
+        }
+        return trustManagers;
+    }
+
+    private TrustManagerFactory getTrustManagerFactory() {
+        final String algorithm = TrustManagerFactory.getDefaultAlgorithm();
+        try {
+            return TrustManagerFactory.getInstance(algorithm);
+        } catch (final NoSuchAlgorithmException e) {
+            final String message = String.format("TrustManagerFactory creation 
failed with algorithm [%s]", algorithm);
+            throw new BuilderConfigurationException(message, e);
+        }
+    }
+}
diff --git 
a/nifi-commons/nifi-security-ssl/src/main/java/org/apache/nifi/security/ssl/TrustManagerBuilder.java
 
b/nifi-commons/nifi-security-ssl/src/main/java/org/apache/nifi/security/ssl/TrustManagerBuilder.java
new file mode 100644
index 0000000000..4140f774c6
--- /dev/null
+++ 
b/nifi-commons/nifi-security-ssl/src/main/java/org/apache/nifi/security/ssl/TrustManagerBuilder.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.security.ssl;
+
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * Builder interface for instances of java.security.ssl.X509TrustManager
+ */
+public interface TrustManagerBuilder {
+    /**
+     * Build X.509 Trust Manager using configured properties
+     *
+     * @return X.509 Trust Manager
+     */
+    X509TrustManager build();
+}
diff --git a/nifi-commons/nifi-site-to-site-client/pom.xml 
b/nifi-commons/nifi-site-to-site-client/pom.xml
index 73ce08b185..bfbefc1e32 100644
--- a/nifi-commons/nifi-site-to-site-client/pom.xml
+++ b/nifi-commons/nifi-site-to-site-client/pom.xml
@@ -51,6 +51,16 @@
             <artifactId>nifi-security-utils</artifactId>
             <version>1.19.0-SNAPSHOT</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-security-utils-api</artifactId>
+            <version>1.19.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-security-ssl</artifactId>
+            <version>1.19.0-SNAPSHOT</version>
+        </dependency>
         <dependency>
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-xml-processing</artifactId>
diff --git 
a/nifi-commons/nifi-site-to-site-client/src/main/java/org/apache/nifi/remote/client/SiteToSiteClient.java
 
b/nifi-commons/nifi-site-to-site-client/src/main/java/org/apache/nifi/remote/client/SiteToSiteClient.java
index 6a91d1dba1..1721f1f61b 100644
--- 
a/nifi-commons/nifi-site-to-site-client/src/main/java/org/apache/nifi/remote/client/SiteToSiteClient.java
+++ 
b/nifi-commons/nifi-site-to-site-client/src/main/java/org/apache/nifi/remote/client/SiteToSiteClient.java
@@ -18,19 +18,17 @@ package org.apache.nifi.remote.client;
 
 import java.io.Closeable;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.Serializable;
 import java.net.InetAddress;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.security.KeyStore;
-import java.security.SecureRandom;
 import java.util.LinkedHashSet;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
-import javax.net.ssl.KeyManagerFactory;
 import javax.net.ssl.SSLContext;
-import javax.net.ssl.TrustManagerFactory;
 import org.apache.nifi.components.state.StateManager;
 import org.apache.nifi.events.EventReporter;
 import org.apache.nifi.remote.Transaction;
@@ -44,8 +42,8 @@ import org.apache.nifi.remote.exception.UnknownPortException;
 import org.apache.nifi.remote.protocol.DataPacket;
 import org.apache.nifi.remote.protocol.SiteToSiteTransportProtocol;
 import org.apache.nifi.remote.protocol.http.HttpProxy;
-import org.apache.nifi.security.util.KeyStoreUtils;
-import org.apache.nifi.security.util.TlsConfiguration;
+import org.apache.nifi.security.ssl.StandardKeyStoreBuilder;
+import org.apache.nifi.security.ssl.StandardSslContextBuilder;
 
 /**
  * <p>
@@ -329,7 +327,7 @@ public interface SiteToSiteClient extends Closeable {
          * Site-to-Site communications are secure (i.e., the client will always
          * use secure or non-secure communications, depending on what the 
server
          * dictates). <b>Note:</b> The SSLContext provided by this method will 
be
-         * ignored if using a Serializable Configuration (see {@link 
#buildSerializableConfig()}).
+         * ignored if using a Serializable Configuration
          * If a Serializable Configuration is required and communications are 
to be
          * secure, the {@link #keystoreFilename(String)}, {@link 
#keystorePass(String)},
          * {@link #keystoreType}, {@link #truststoreFilename}, {@link 
#truststorePass(String)},
@@ -755,8 +753,6 @@ public interface SiteToSiteClient extends Closeable {
 
     }
 
-
-    @SuppressWarnings("deprecation")
     class StandardSiteToSiteClientConfig implements SiteToSiteClientConfig, 
Serializable {
 
         private static final long serialVersionUID = 1L;
@@ -882,45 +878,48 @@ public interface SiteToSiteClient extends Closeable {
                 return sslContext;
             }
 
-            final KeyManagerFactory keyManagerFactory;
+            final KeyStore keyStore;
             if (keystoreFilename != null && keystorePass != null && 
keystoreType != null) {
-                try {
-                    // prepare the keystore
-                    final KeyStore keyStore = 
KeyStoreUtils.getKeyStore(getKeystoreType().name());
-                    try (final InputStream keyStoreStream = new 
FileInputStream(new File(getKeystoreFilename()))) {
-                        keyStore.load(keyStoreStream, 
keystorePass.toCharArray());
-                    }
-                    keyManagerFactory = 
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
-                    keyManagerFactory.init(keyStore, 
keystorePass.toCharArray());
-                } catch (final Exception e) {
-                    throw new IllegalStateException("Failed to load Keystore", 
e);
+                try (final InputStream keyStoreStream = 
Files.newInputStream(Paths.get(keystoreFilename))) {
+                    keyStore = new StandardKeyStoreBuilder()
+                            .inputStream(keyStoreStream)
+                            .password(keystorePass.toCharArray())
+                            .type(keystoreType.name())
+                            .build();
+                } catch (final IOException e) {
+                    throw new IllegalStateException(String.format("Read Key 
Store [%s] failed", keystoreFilename), e);
                 }
             } else {
-                keyManagerFactory = null;
+                keyStore = null;
             }
 
-            final TrustManagerFactory trustManagerFactory;
+            final KeyStore trustStore;
             if (truststoreFilename != null && truststorePass != null && 
truststoreType != null) {
-                try {
-                    trustManagerFactory = 
KeyStoreUtils.loadTrustManagerFactory(truststoreFilename, truststorePass, 
getTruststoreType().name());
-                } catch (final Exception e) {
-                    throw new IllegalStateException("Failed to load 
Truststore", e);
+                try (final InputStream keyStoreStream = 
Files.newInputStream(Paths.get(truststoreFilename))) {
+                    trustStore = new StandardKeyStoreBuilder()
+                            .inputStream(keyStoreStream)
+                            .password(truststorePass.toCharArray())
+                            .type(truststoreType.name())
+                            .build();
+                } catch (final IOException e) {
+                    throw new IllegalStateException(String.format("Read Trust 
Store [%s] failed", truststoreFilename), e);
                 }
             } else {
-                trustManagerFactory = null;
+                trustStore = null;
             }
 
-            if (keyManagerFactory != null && trustManagerFactory != null) {
-                try {
-                    // initialize the ssl context
-                    final SSLContext sslContext = 
SSLContext.getInstance(TlsConfiguration.getHighestCurrentSupportedTlsProtocolVersion());
-                    sslContext.init(keyManagerFactory.getKeyManagers(), 
trustManagerFactory.getTrustManagers(), new SecureRandom());
-                    
sslContext.getDefaultSSLParameters().setNeedClientAuth(true);
+            if (keyStore != null || trustStore != null) {
+                final StandardSslContextBuilder builder = new 
StandardSslContextBuilder();
 
-                    return sslContext;
-                } catch (final Exception e) {
-                    throw new IllegalStateException("Created keystore and 
truststore but failed to initialize SSLContext", e);
+                if (keyStore != null) {
+                    final char[] keyPassword = keystorePass.toCharArray();
+                    builder.keyPassword(keyPassword);
+                    builder.keyStore(keyStore);
+                }
+                if (trustStore != null) {
+                    builder.trustStore(trustStore);
                 }
+                return builder.build();
             } else {
                 return null;
             }
diff --git 
a/nifi-commons/nifi-site-to-site-client/src/test/java/org/apache/nifi/remote/client/http/TestHttpClient.java
 
b/nifi-commons/nifi-site-to-site-client/src/test/java/org/apache/nifi/remote/client/http/TestHttpClient.java
index e26b4b6638..93a1fe8def 100644
--- 
a/nifi-commons/nifi-site-to-site-client/src/test/java/org/apache/nifi/remote/client/http/TestHttpClient.java
+++ 
b/nifi-commons/nifi-site-to-site-client/src/test/java/org/apache/nifi/remote/client/http/TestHttpClient.java
@@ -1377,6 +1377,6 @@ public class TestHttpClient {
     }
 
     private static void setTlsConfiguration() {
-        tlsConfiguration = new TemporaryKeyStoreBuilder().build();
+        tlsConfiguration = new 
TemporaryKeyStoreBuilder().trustStoreType(KeystoreType.JKS.name()).build();
     }
 }
diff --git a/nifi-registry/nifi-registry-core/nifi-registry-client/pom.xml 
b/nifi-registry/nifi-registry-core/nifi-registry-client/pom.xml
index 91751dba2b..8f1ab84f49 100644
--- a/nifi-registry/nifi-registry-core/nifi-registry-client/pom.xml
+++ b/nifi-registry/nifi-registry-core/nifi-registry-client/pom.xml
@@ -31,6 +31,11 @@
             <artifactId>nifi-registry-security-utils</artifactId>
             <version>1.19.0-SNAPSHOT</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-security-ssl</artifactId>
+            <version>1.19.0-SNAPSHOT</version>
+        </dependency>
         <dependency>
             <groupId>org.glassfish.jersey.core</groupId>
             <artifactId>jersey-client</artifactId>
diff --git 
a/nifi-registry/nifi-registry-core/nifi-registry-client/src/main/java/org/apache/nifi/registry/client/NiFiRegistryClientConfig.java
 
b/nifi-registry/nifi-registry-core/nifi-registry-client/src/main/java/org/apache/nifi/registry/client/NiFiRegistryClientConfig.java
index 784f77fc99..95ff6d12b1 100644
--- 
a/nifi-registry/nifi-registry-core/nifi-registry-client/src/main/java/org/apache/nifi/registry/client/NiFiRegistryClientConfig.java
+++ 
b/nifi-registry/nifi-registry-core/nifi-registry-client/src/main/java/org/apache/nifi/registry/client/NiFiRegistryClientConfig.java
@@ -16,28 +16,24 @@
  */
 package org.apache.nifi.registry.client;
 
-import org.apache.nifi.registry.security.util.CertificateUtils;
-import org.apache.nifi.registry.security.util.KeyStoreUtils;
 import org.apache.nifi.registry.security.util.KeystoreType;
+import org.apache.nifi.security.ssl.StandardKeyStoreBuilder;
+import org.apache.nifi.security.ssl.StandardSslContextBuilder;
 
 import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.KeyManagerFactory;
 import javax.net.ssl.SSLContext;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-import java.io.File;
-import java.io.FileInputStream;
+import java.io.IOException;
 import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.security.KeyStore;
-import java.security.SecureRandom;
 
 /**
  * Configuration for a NiFiRegistryClient.
  */
 public class NiFiRegistryClientConfig {
 
-    public static final String DEFAULT_PROTOCOL = 
CertificateUtils.getHighestCurrentSupportedTlsProtocolVersion();
+    private static final String DEFAULT_PROTOCOL = "TLS";
 
     private final String baseUrl;
     private final SSLContext sslContext;
@@ -79,58 +75,49 @@ public class NiFiRegistryClientConfig {
             return sslContext;
         }
 
-        final KeyManagerFactory keyManagerFactory;
+        final KeyStore keyStore;
         if (keystoreFilename != null && keystorePass != null && keystoreType 
!= null) {
-            try {
-                // prepare the keystore
-                final KeyStore keyStore = 
KeyStoreUtils.getKeyStore(keystoreType.name());
-                try (final InputStream keyStoreStream = new 
FileInputStream(new File(keystoreFilename))) {
-                    keyStore.load(keyStoreStream, keystorePass.toCharArray());
-                }
-                keyManagerFactory = 
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
-
-                if (keyPass == null) {
-                    keyManagerFactory.init(keyStore, 
keystorePass.toCharArray());
-                } else {
-                    keyManagerFactory.init(keyStore, keyPass.toCharArray());
-                }
-            } catch (final Exception e) {
-                throw new IllegalStateException("Failed to load Keystore", e);
+            try (final InputStream keyStoreStream = 
Files.newInputStream(Paths.get(keystoreFilename))) {
+                keyStore = new StandardKeyStoreBuilder()
+                        .inputStream(keyStoreStream)
+                        .password(keystorePass.toCharArray())
+                        .type(keystoreType.name())
+                        .build();
+            } catch (final IOException e) {
+                throw new IllegalStateException(String.format("Read Key Store 
[%s] failed", keystoreFilename), e);
             }
         } else {
-            keyManagerFactory = null;
+            keyStore = null;
         }
 
-        final TrustManagerFactory trustManagerFactory;
+        final KeyStore trustStore;
         if (truststoreFilename != null && truststorePass != null && 
truststoreType != null) {
-            try {
-                // prepare the truststore
-                final KeyStore trustStore = 
KeyStoreUtils.getKeyStore(truststoreType.name());
-                try (final InputStream trustStoreStream = new 
FileInputStream(new File(truststoreFilename))) {
-                    trustStore.load(trustStoreStream, 
truststorePass.toCharArray());
-                }
-                trustManagerFactory = 
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
-                trustManagerFactory.init(trustStore);
-            } catch (final Exception e) {
-                throw new IllegalStateException("Failed to load Truststore", 
e);
+            try (final InputStream keyStoreStream = 
Files.newInputStream(Paths.get(truststoreFilename))) {
+                trustStore = new StandardKeyStoreBuilder()
+                        .inputStream(keyStoreStream)
+                        .password(truststorePass.toCharArray())
+                        .type(truststoreType.name())
+                        .build();
+            } catch (final IOException e) {
+                throw new IllegalStateException(String.format("Read Trust 
Store [%s] failed", truststoreFilename), e);
             }
         } else {
-            trustManagerFactory = null;
+            trustStore = null;
         }
 
-        if (keyManagerFactory != null || trustManagerFactory != null) {
-            try {
-                // initialize the ssl context
-                KeyManager[] keyManagers = keyManagerFactory != null ? 
keyManagerFactory.getKeyManagers() : null;
-                TrustManager[] trustManagers = trustManagerFactory != null ? 
trustManagerFactory.getTrustManagers() : null;
-                final SSLContext sslContext = 
SSLContext.getInstance(getProtocol());
-                sslContext.init(keyManagers, trustManagers, new 
SecureRandom());
-                sslContext.getDefaultSSLParameters().setNeedClientAuth(true);
-
-                return sslContext;
-            } catch (final Exception e) {
-                throw new IllegalStateException("Created keystore and 
truststore but failed to initialize SSLContext", e);
+        if (keyStore != null || trustStore != null) {
+            final StandardSslContextBuilder builder = new 
StandardSslContextBuilder();
+            builder.protocol(protocol);
+
+            if (keyStore != null) {
+                final char[] keyPassword = keyPass == null ? 
keystorePass.toCharArray() : keyPass.toCharArray();
+                builder.keyPassword(keyPassword);
+                builder.keyStore(keyStore);
+            }
+            if (trustStore != null) {
+                builder.trustStore(trustStore);
             }
+            return builder.build();
         } else {
             return null;
         }
diff --git a/nifi-registry/nifi-registry-core/nifi-registry-framework/pom.xml 
b/nifi-registry/nifi-registry-core/nifi-registry-framework/pom.xml
index 77dcc7e5a4..1cff5c0cba 100644
--- a/nifi-registry/nifi-registry-core/nifi-registry-framework/pom.xml
+++ b/nifi-registry/nifi-registry-core/nifi-registry-framework/pom.xml
@@ -211,6 +211,11 @@
             <artifactId>nifi-h2-database-migrator</artifactId>
             <version>1.19.0-SNAPSHOT</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-security-ssl</artifactId>
+            <version>1.19.0-SNAPSHOT</version>
+        </dependency>
         <dependency>
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-xml-processing</artifactId>
diff --git 
a/nifi-registry/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/ldap/LdapIdentityProvider.java
 
b/nifi-registry/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/ldap/LdapIdentityProvider.java
index 4427ed951d..47760c1c86 100644
--- 
a/nifi-registry/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/ldap/LdapIdentityProvider.java
+++ 
b/nifi-registry/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/ldap/LdapIdentityProvider.java
@@ -26,9 +26,9 @@ import 
org.apache.nifi.registry.security.authentication.exception.IdentityAccess
 import 
org.apache.nifi.registry.security.authentication.exception.InvalidCredentialsException;
 import 
org.apache.nifi.registry.security.exception.SecurityProviderCreationException;
 import 
org.apache.nifi.registry.security.exception.SecurityProviderDestructionException;
-import org.apache.nifi.registry.security.util.SslContextFactory;
-import org.apache.nifi.registry.security.util.SslContextFactory.ClientAuth;
 import org.apache.nifi.registry.util.FormatUtils;
+import org.apache.nifi.security.ssl.StandardKeyStoreBuilder;
+import org.apache.nifi.security.ssl.StandardSslContextBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.ldap.AuthenticationException;
@@ -49,12 +49,9 @@ import 
org.springframework.security.ldap.userdetails.LdapUserDetails;
 
 import javax.naming.Context;
 import javax.net.ssl.SSLContext;
+import java.io.FileInputStream;
 import java.io.IOException;
-import java.security.KeyManagementException;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.CertificateException;
+import java.security.KeyStore;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
@@ -79,8 +76,9 @@ public class LdapIdentityProvider extends 
BasicAuthIdentityProvider implements I
             throw new SecurityProviderCreationException("The Authentication 
Expiration must be specified.");
         }
 
+
         try {
-            expiration = FormatUtils.getTimeDuration(rawExpiration, 
TimeUnit.MILLISECONDS);
+            expiration = 
Math.round(FormatUtils.getPreciseTimeDuration(rawExpiration, 
TimeUnit.MILLISECONDS));
         } catch (final IllegalArgumentException iae) {
             throw new SecurityProviderCreationException(String.format("The 
Expiration Duration '%s' is not a valid time duration", rawExpiration));
         }
@@ -243,12 +241,11 @@ public class LdapIdentityProvider extends 
BasicAuthIdentityProvider implements I
         try {
             final String username = authenticationRequest.getUsername();
             final Object credentials = authenticationRequest.getCredentials();
-            final String password = credentials != null && credentials 
instanceof String ? (String) credentials : null;
 
             // perform the authentication
             final UsernamePasswordAuthenticationToken token = new 
UsernamePasswordAuthenticationToken(username, credentials);
             final Authentication authentication = 
ldapAuthenticationProvider.authenticate(token);
-            logger.debug("Created authentication token: {}", token.toString());
+            logger.debug("Created authentication token: {}", token);
 
             // use dn if configured
             if (IdentityStrategy.USE_DN.equals(identityStrategy)) {
@@ -294,8 +291,8 @@ public class LdapIdentityProvider extends 
BasicAuthIdentityProvider implements I
         final String rawTimeout = 
configurationContext.getProperty(configurationProperty);
         if (StringUtils.isNotBlank(rawTimeout)) {
             try {
-                final Long timeout = FormatUtils.getTimeDuration(rawTimeout, 
TimeUnit.MILLISECONDS);
-                baseEnvironment.put(environmentKey, timeout.toString());
+                final long timeout = 
Math.round(FormatUtils.getPreciseTimeDuration(rawTimeout, 
TimeUnit.MILLISECONDS));
+                baseEnvironment.put(environmentKey, Long.toString(timeout));
             } catch (final IllegalArgumentException iae) {
                 throw new SecurityProviderCreationException(String.format("The 
%s '%s' is not a valid time duration", configurationProperty, rawTimeout));
             }
@@ -309,7 +306,6 @@ public class LdapIdentityProvider extends 
BasicAuthIdentityProvider implements I
         final String rawTruststore = configurationContext.getProperty("TLS - 
Truststore");
         final String rawTruststorePassword = 
configurationContext.getProperty("TLS - Truststore Password");
         final String rawTruststoreType = configurationContext.getProperty("TLS 
- Truststore Type");
-        final String rawClientAuth = configurationContext.getProperty("TLS - 
Client Auth");
         final String rawProtocol = configurationContext.getProperty("TLS - 
Protocol");
 
         // create the ssl context
@@ -323,29 +319,32 @@ public class LdapIdentityProvider extends 
BasicAuthIdentityProvider implements I
                     throw new SecurityProviderCreationException("TLS - 
Protocol must be specified.");
                 }
 
-                if (StringUtils.isBlank(rawKeystore)) {
-                    sslContext = 
SslContextFactory.createTrustSslContext(rawTruststore, 
rawTruststorePassword.toCharArray(), rawTruststoreType, rawProtocol);
-                } else if (StringUtils.isBlank(rawTruststore)) {
-                    sslContext = 
SslContextFactory.createSslContext(rawKeystore, 
rawKeystorePassword.toCharArray(), rawKeystoreType, rawProtocol);
-                } else {
-                    // determine the client auth if specified
-                    final ClientAuth clientAuth;
-                    if (StringUtils.isBlank(rawClientAuth)) {
-                        clientAuth = ClientAuth.NONE;
-                    } else {
-                        try {
-                            clientAuth = ClientAuth.valueOf(rawClientAuth);
-                        } catch (final IllegalArgumentException iae) {
-                            throw new 
SecurityProviderCreationException(String.format("Unrecognized client auth '%s'. 
Possible values are [%s]",
-                                    rawClientAuth, 
StringUtils.join(ClientAuth.values(), ", ")));
-                        }
+                final StandardSslContextBuilder sslContextBuilder = new 
StandardSslContextBuilder().protocol(rawProtocol);
+
+                if (StringUtils.isNotBlank(rawTruststore)) {
+                    try (final FileInputStream trustStoreStream = new 
FileInputStream(rawTruststore)) {
+                        final KeyStore trustStore = new 
StandardKeyStoreBuilder()
+                                .type(rawTruststoreType)
+                                .password(rawTruststorePassword.toCharArray())
+                                .inputStream(trustStoreStream).build();
+                        sslContextBuilder.trustStore(trustStore);
                     }
+                }
 
-                    sslContext = 
SslContextFactory.createSslContext(rawKeystore, 
rawKeystorePassword.toCharArray(), rawKeystoreType,
-                            rawTruststore, 
rawTruststorePassword.toCharArray(), rawTruststoreType, clientAuth, 
rawProtocol);
+                if (StringUtils.isNotBlank(rawKeystore)) {
+                    try (final FileInputStream keyStoreStream = new 
FileInputStream(rawKeystore)) {
+                        final KeyStore keyStore = new StandardKeyStoreBuilder()
+                                .type(rawKeystoreType)
+                                .password(rawKeystorePassword.toCharArray())
+                                .inputStream(keyStoreStream).build();
+                        sslContextBuilder.keyStore(keyStore);
+                        
sslContextBuilder.keyPassword(rawKeystorePassword.toCharArray());
+                    }
                 }
+
+                sslContext = sslContextBuilder.build();
             }
-        } catch (final KeyStoreException | NoSuchAlgorithmException | 
CertificateException | UnrecoverableKeyException | KeyManagementException | 
IOException e) {
+        } catch (final RuntimeException | IOException e) {
             throw new SecurityProviderCreationException(e.getMessage(), e);
         }
 
diff --git 
a/nifi-registry/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/ldap/tenants/LdapUserGroupProvider.java
 
b/nifi-registry/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/ldap/tenants/LdapUserGroupProvider.java
index 8ecd56d358..39664d12cd 100644
--- 
a/nifi-registry/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/ldap/tenants/LdapUserGroupProvider.java
+++ 
b/nifi-registry/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/ldap/tenants/LdapUserGroupProvider.java
@@ -31,10 +31,10 @@ import 
org.apache.nifi.registry.security.identity.IdentityMapper;
 import org.apache.nifi.registry.security.ldap.LdapAuthenticationStrategy;
 import org.apache.nifi.registry.security.ldap.LdapsSocketFactory;
 import org.apache.nifi.registry.security.ldap.ReferralStrategy;
-import org.apache.nifi.registry.security.util.SslContextFactory;
-import org.apache.nifi.registry.security.util.SslContextFactory.ClientAuth;
 import org.apache.nifi.registry.util.FormatUtils;
 import org.apache.nifi.registry.util.PropertyValue;
+import org.apache.nifi.security.ssl.StandardKeyStoreBuilder;
+import org.apache.nifi.security.ssl.StandardSslContextBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.ldap.control.PagedResultsDirContextProcessor;
@@ -60,12 +60,9 @@ import javax.naming.NamingException;
 import javax.naming.directory.Attribute;
 import javax.naming.directory.SearchControls;
 import javax.net.ssl.SSLContext;
+import java.io.FileInputStream;
 import java.io.IOException;
-import java.security.KeyManagementException;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.CertificateException;
+import java.security.KeyStore;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -116,7 +113,7 @@ public class LdapUserGroupProvider implements 
UserGroupProvider {
     private IdentityMapper identityMapper;
 
     private ScheduledExecutorService ldapSync;
-    private AtomicReference<TenantHolder> tenants = new 
AtomicReference<>(null);
+    private final AtomicReference<TenantHolder> tenants = new 
AtomicReference<>(null);
 
     private String userSearchBase;
     private SearchScope userSearchScope;
@@ -366,7 +363,7 @@ public class LdapUserGroupProvider implements 
UserGroupProvider {
         final long syncInterval;
         if (rawSyncInterval.isSet()) {
             try {
-                syncInterval = 
FormatUtils.getTimeDuration(rawSyncInterval.getValue(), TimeUnit.MILLISECONDS);
+                syncInterval = 
Math.round(FormatUtils.getPreciseTimeDuration(rawSyncInterval.getValue(), 
TimeUnit.MILLISECONDS));
             } catch (final IllegalArgumentException iae) {
                 throw new SecurityProviderCreationException(String.format("The 
%s '%s' is not a valid time duration", PROP_SYNC_INTERVAL, 
rawSyncInterval.getValue()));
             }
@@ -389,7 +386,7 @@ public class LdapUserGroupProvider implements 
UserGroupProvider {
                 try {
                     load(context);
                 } catch (final Throwable t) {
-                    logger.error("Failed to sync User/Groups from LDAP due to 
{}. Will try again in {} millis.", new Object[] {t.toString(), syncInterval});
+                    logger.error("Failed to sync User/Groups from LDAP due to 
{}. Will try again in {} millis.", t, syncInterval);
                     if (logger.isDebugEnabled()) {
                         logger.error("", t);
                     }
@@ -560,8 +557,6 @@ public class LdapUserGroupProvider implements 
UserGroupProvider {
                     groupList.addAll(ldapTemplate.search(groupSearchBase, 
groupFilter.encode(), groupControls, new AbstractContextMapper<Group>() {
                         @Override
                         protected Group doMapFromContext(DirContextOperations 
ctx) {
-                            final String dn = ctx.getDn().toString();
-
                             // get the group identity
                             final String name = getGroupName(ctx);
 
@@ -630,7 +625,7 @@ public class LdapUserGroupProvider implements 
UserGroupProvider {
 
                             // add all users that were associated with this 
referenced group attribute
                             if 
(groupToUserIdentifierMappings.containsKey(referencedGroupValue)) {
-                                
groupToUserIdentifierMappings.remove(referencedGroupValue).forEach(userIdentifier
 -> groupBuilder.addUser(userIdentifier));
+                                
groupToUserIdentifierMappings.remove(referencedGroupValue).forEach(groupBuilder::addUser);
                             }
 
                             return groupBuilder.build();
@@ -639,11 +634,10 @@ public class LdapUserGroupProvider implements 
UserGroupProvider {
                 } while (hasMorePages(groupProcessor));
 
                 // any remaining groupDn's were referenced by a user but not 
found while searching groups
-                groupToUserIdentifierMappings.forEach((referencedGroupValue, 
userIdentifiers) -> {
-                    logger.debug(String.format("[%s] are members of %s but 
that group was not found while searching groups. " +
-                                    "This may be due to misconfiguration or 
because that group is not a NiFi Registry group as defined by the Group Search 
Base and Filter. " +
-                                    "Ignoring group membership.", 
StringUtils.join(userIdentifiers, ", "), referencedGroupValue));
-                });
+                groupToUserIdentifierMappings.forEach((referencedGroupValue, 
userIdentifiers) -> logger.debug(String.format(
+                                "[%s] are members of %s but that group was not 
found while searching groups. " +
+                                "This may be due to misconfiguration or 
because that group is not a NiFi Registry group as defined by the Group Search 
Base and Filter. " +
+                                "Ignoring group membership.", 
StringUtils.join(userIdentifiers, ", "), referencedGroupValue)));
             } else {
                 // since performGroupSearch is false, then the referenced user 
attribute must be blank... the group value must be the dn
 
@@ -661,7 +655,7 @@ public class LdapUserGroupProvider implements 
UserGroupProvider {
                     final Group.Builder groupBuilder = new 
Group.Builder().identifierGenerateFromSeed(groupName).name(groupName);
 
                     // add each user
-                    userIdentifiers.forEach(userIdentifier -> 
groupBuilder.addUser(userIdentifier));
+                    userIdentifiers.forEach(groupBuilder::addUser);
 
                     // build the group
                     groupList.add(groupBuilder.build());
@@ -799,8 +793,8 @@ public class LdapUserGroupProvider implements 
UserGroupProvider {
         final PropertyValue rawTimeout = 
configurationContext.getProperty(configurationProperty);
         if (rawTimeout.isSet()) {
             try {
-                final Long timeout = 
FormatUtils.getTimeDuration(rawTimeout.getValue(), TimeUnit.MILLISECONDS);
-                baseEnvironment.put(environmentKey, timeout.toString());
+                final long timeout = 
Math.round(FormatUtils.getPreciseTimeDuration(rawTimeout.getValue(), 
TimeUnit.MILLISECONDS));
+                baseEnvironment.put(environmentKey, Long.toString(timeout));
             } catch (final IllegalArgumentException iae) {
                 throw new SecurityProviderCreationException(String.format("The 
%s '%s' is not a valid time duration", configurationProperty, rawTimeout));
             }
@@ -814,7 +808,6 @@ public class LdapUserGroupProvider implements 
UserGroupProvider {
         final String rawTruststore = configurationContext.getProperty("TLS - 
Truststore").getValue();
         final String rawTruststorePassword = 
configurationContext.getProperty("TLS - Truststore Password").getValue();
         final String rawTruststoreType = configurationContext.getProperty("TLS 
- Truststore Type").getValue();
-        final String rawClientAuth = configurationContext.getProperty("TLS - 
Client Auth").getValue();
         final String rawProtocol = configurationContext.getProperty("TLS - 
Protocol").getValue();
 
         // create the ssl context
@@ -828,29 +821,32 @@ public class LdapUserGroupProvider implements 
UserGroupProvider {
                     throw new SecurityProviderCreationException("TLS - 
Protocol must be specified.");
                 }
 
-                if (StringUtils.isBlank(rawKeystore)) {
-                    sslContext = 
SslContextFactory.createTrustSslContext(rawTruststore, 
rawTruststorePassword.toCharArray(), rawTruststoreType, rawProtocol);
-                } else if (StringUtils.isBlank(rawTruststore)) {
-                    sslContext = 
SslContextFactory.createSslContext(rawKeystore, 
rawKeystorePassword.toCharArray(), rawKeystoreType, rawProtocol);
-                } else {
-                    // determine the client auth if specified
-                    final ClientAuth clientAuth;
-                    if (StringUtils.isBlank(rawClientAuth)) {
-                        clientAuth = ClientAuth.NONE;
-                    } else {
-                        try {
-                            clientAuth = ClientAuth.valueOf(rawClientAuth);
-                        } catch (final IllegalArgumentException iae) {
-                            throw new 
SecurityProviderCreationException(String.format("Unrecognized client auth '%s'. 
Possible values are [%s]",
-                                    rawClientAuth, 
StringUtils.join(ClientAuth.values(), ", ")));
-                        }
+                final StandardSslContextBuilder sslContextBuilder = new 
StandardSslContextBuilder().protocol(rawProtocol);
+
+                if (StringUtils.isNotBlank(rawTruststore)) {
+                    try (final FileInputStream trustStoreStream = new 
FileInputStream(rawTruststore)) {
+                        final KeyStore trustStore = new 
StandardKeyStoreBuilder()
+                                .type(rawTruststoreType)
+                                .password(rawTruststorePassword.toCharArray())
+                                .inputStream(trustStoreStream).build();
+                        sslContextBuilder.trustStore(trustStore);
                     }
+                }
 
-                    sslContext = 
SslContextFactory.createSslContext(rawKeystore, 
rawKeystorePassword.toCharArray(), rawKeystoreType,
-                            rawTruststore, 
rawTruststorePassword.toCharArray(), rawTruststoreType, clientAuth, 
rawProtocol);
+                if (StringUtils.isNotBlank(rawKeystore)) {
+                    try (final FileInputStream keyStoreStream = new 
FileInputStream(rawKeystore)) {
+                        final KeyStore keyStore = new StandardKeyStoreBuilder()
+                                .type(rawKeystoreType)
+                                .password(rawKeystorePassword.toCharArray())
+                                .inputStream(keyStoreStream).build();
+                        sslContextBuilder.keyStore(keyStore);
+                        
sslContextBuilder.keyPassword(rawKeystorePassword.toCharArray());
+                    }
                 }
+
+                sslContext = sslContextBuilder.build();
             }
-        } catch (final KeyStoreException | NoSuchAlgorithmException | 
CertificateException | UnrecoverableKeyException | KeyManagementException | 
IOException e) {
+        } catch (final RuntimeException | IOException e) {
             throw new SecurityProviderCreationException(e.getMessage(), e);
         }
 
diff --git 
a/nifi-registry/nifi-registry-core/nifi-registry-security-utils/src/main/java/org/apache/nifi/registry/security/util/CertificateUtils.java
 
b/nifi-registry/nifi-registry-core/nifi-registry-security-utils/src/main/java/org/apache/nifi/registry/security/util/CertificateUtils.java
deleted file mode 100644
index d766b577b8..0000000000
--- 
a/nifi-registry/nifi-registry-core/nifi-registry-security-utils/src/main/java/org/apache/nifi/registry/security/util/CertificateUtils.java
+++ /dev/null
@@ -1,671 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.registry.security.util;
-
-import org.apache.commons.lang3.StringUtils;
-import org.bouncycastle.asn1.ASN1Encodable;
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.ASN1Set;
-import org.bouncycastle.asn1.DERSequence;
-import org.bouncycastle.asn1.pkcs.Attribute;
-import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
-import org.bouncycastle.asn1.x500.AttributeTypeAndValue;
-import org.bouncycastle.asn1.x500.RDN;
-import org.bouncycastle.asn1.x500.X500Name;
-import org.bouncycastle.asn1.x500.style.BCStyle;
-import org.bouncycastle.asn1.x509.BasicConstraints;
-import org.bouncycastle.asn1.x509.ExtendedKeyUsage;
-import org.bouncycastle.asn1.x509.Extension;
-import org.bouncycastle.asn1.x509.Extensions;
-import org.bouncycastle.asn1.x509.KeyPurposeId;
-import org.bouncycastle.asn1.x509.KeyUsage;
-import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
-import org.bouncycastle.cert.CertIOException;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.cert.X509v3CertificateBuilder;
-import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
-import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
-import org.bouncycastle.operator.ContentSigner;
-import org.bouncycastle.operator.OperatorCreationException;
-import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
-import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.naming.InvalidNameException;
-import javax.naming.ldap.LdapName;
-import javax.naming.ldap.Rdn;
-import javax.net.ssl.SSLPeerUnverifiedException;
-import javax.net.ssl.SSLSocket;
-import java.io.ByteArrayInputStream;
-import java.math.BigInteger;
-import java.net.Socket;
-import java.security.KeyPair;
-import java.security.NoSuchAlgorithmException;
-import java.security.PublicKey;
-import java.security.Security;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.CertificateParsingException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public final class CertificateUtils {
-    private static final Logger logger = 
LoggerFactory.getLogger(CertificateUtils.class);
-    private static final String PEER_NOT_AUTHENTICATED_MSG = "peer not 
authenticated";
-    private static final Map<ASN1ObjectIdentifier, Integer> dnOrderMap = 
createDnOrderMap();
-
-    public static final String JAVA_8_MAX_SUPPORTED_TLS_PROTOCOL_VERSION = 
"TLSv1.2";
-    public static final String JAVA_11_MAX_SUPPORTED_TLS_PROTOCOL_VERSION = 
"TLSv1.3";
-    public static final String[] JAVA_8_SUPPORTED_TLS_PROTOCOL_VERSIONS = new 
String[]{JAVA_8_MAX_SUPPORTED_TLS_PROTOCOL_VERSION};
-    public static final String[] JAVA_11_SUPPORTED_TLS_PROTOCOL_VERSIONS = new 
String[]{JAVA_11_MAX_SUPPORTED_TLS_PROTOCOL_VERSION, 
JAVA_8_MAX_SUPPORTED_TLS_PROTOCOL_VERSION};
-
-    static {
-        Security.addProvider(new BouncyCastleProvider());
-    }
-
-    /**
-     * The time in milliseconds that the last unique serial number was 
generated
-     */
-    private static long lastSerialNumberMillis = 0L;
-
-    /**
-     * An incrementor to add uniqueness to serial numbers generated in the 
same millisecond
-     */
-    private static int serialNumberIncrementor = 0;
-
-    /**
-     * BigInteger value to use for the base of the unique serial number
-     */
-    private static BigInteger millisecondBigInteger;
-
-    private static Map<ASN1ObjectIdentifier, Integer> createDnOrderMap() {
-        Map<ASN1ObjectIdentifier, Integer> orderMap = new HashMap<>();
-        int count = 0;
-        orderMap.put(BCStyle.CN, count++);
-        orderMap.put(BCStyle.L, count++);
-        orderMap.put(BCStyle.ST, count++);
-        orderMap.put(BCStyle.O, count++);
-        orderMap.put(BCStyle.OU, count++);
-        orderMap.put(BCStyle.C, count++);
-        orderMap.put(BCStyle.STREET, count++);
-        orderMap.put(BCStyle.DC, count++);
-        orderMap.put(BCStyle.UID, count++);
-        return Collections.unmodifiableMap(orderMap);
-    }
-
-    /**
-     * Extracts the username from the specified DN. If the username cannot be 
extracted because the CN is in an unrecognized format, the entire CN is 
returned. If the CN cannot be extracted because
-     * the DN is in an unrecognized format, the entire DN is returned.
-     *
-     * @param dn the dn to extract the username from
-     * @return the exatracted username
-     */
-    public static String extractUsername(String dn) {
-        String username = dn;
-
-        // ensure the dn is specified
-        if (StringUtils.isNotBlank(dn)) {
-            // determine the separate
-            final String separator = StringUtils.indexOfIgnoreCase(dn, "/cn=") 
> 0 ? "/" : ",";
-
-            // attempt to locate the cd
-            final String cnPattern = "cn=";
-            final int cnIndex = StringUtils.indexOfIgnoreCase(dn, cnPattern);
-            if (cnIndex >= 0) {
-                int separatorIndex = StringUtils.indexOf(dn, separator, 
cnIndex);
-                if (separatorIndex > 0) {
-                    username = StringUtils.substring(dn, cnIndex + 
cnPattern.length(), separatorIndex);
-                } else {
-                    username = StringUtils.substring(dn, cnIndex + 
cnPattern.length());
-                }
-            }
-        }
-
-        return username;
-    }
-
-    /**
-     * Returns a list of subject alternative names. Any name that is 
represented as a String by X509Certificate.getSubjectAlternativeNames() is 
converted to lowercase and returned.
-     *
-     * @param certificate a certificate
-     * @return a list of subject alternative names; list is never null
-     * @throws CertificateParsingException if parsing the certificate failed
-     */
-    public static List<String> getSubjectAlternativeNames(final 
X509Certificate certificate) throws CertificateParsingException {
-
-        final Collection<List<?>> altNames = 
certificate.getSubjectAlternativeNames();
-        if (altNames == null) {
-            return new ArrayList<>();
-        }
-
-        final List<String> result = new ArrayList<>();
-        for (final List<?> generalName : altNames) {
-            /**
-             * generalName has the name type as the first element a String or 
byte array for the second element. We return any general names that are String 
types.
-             *
-             * We don't inspect the numeric name type because some 
certificates incorrectly put IPs and DNS names under the wrong name types.
-             */
-            final Object value = generalName.get(1);
-            if (value instanceof String) {
-                result.add(((String) value).toLowerCase());
-            }
-
-        }
-
-        return result;
-    }
-
-    /**
-     * Returns the DN extracted from the peer certificate (the server DN if 
run on the client; the client DN (if available) if run on the server).
-     * <p>
-     * If the client auth setting is WANT or NONE and a client certificate is 
not present, this method will return {@code null}.
-     * If the client auth is NEED, it will throw a {@link 
CertificateException}.
-     *
-     * @param socket the SSL Socket
-     * @return the extracted DN
-     * @throws CertificateException if there is a problem parsing the 
certificate
-     */
-    public static String extractPeerDNFromSSLSocket(Socket socket) throws 
CertificateException {
-        String dn = null;
-        if (socket instanceof SSLSocket) {
-            final SSLSocket sslSocket = (SSLSocket) socket;
-
-            boolean clientMode = sslSocket.getUseClientMode();
-            logger.debug("SSL Socket in {} mode", clientMode ? "client" : 
"server");
-            SslContextFactory.ClientAuth clientAuth = 
getClientAuthStatus(sslSocket);
-            logger.debug("SSL Socket client auth status: {}", clientAuth);
-
-            if (clientMode) {
-                logger.debug("This socket is in client mode, so attempting to 
extract certificate from remote 'server' socket");
-                dn = extractPeerDNFromServerSSLSocket(sslSocket);
-            } else {
-                logger.debug("This socket is in server mode, so attempting to 
extract certificate from remote 'client' socket");
-                dn = extractPeerDNFromClientSSLSocket(sslSocket);
-            }
-        }
-
-        return dn;
-    }
-
-    /**
-     * Returns the DN extracted from the client certificate.
-     * <p>
-     * If the client auth setting is WANT or NONE and a certificate is not 
present (and {@code respectClientAuth} is {@code true}), this method will 
return {@code null}.
-     * If the client auth is NEED, it will throw a {@link 
CertificateException}.
-     *
-     * @param sslSocket the SSL Socket
-     * @return the extracted DN
-     * @throws CertificateException if there is a problem parsing the 
certificate
-     */
-    private static String extractPeerDNFromClientSSLSocket(SSLSocket 
sslSocket) throws CertificateException {
-        String dn = null;
-
-        /** The clientAuth value can be "need", "want", or "none"
-         * A client must send client certificates for need, should for want, 
and will not for none.
-         * This method should throw an exception if none are provided for 
need, return null if none are provided for want, and return null (without 
checking) for none.
-         */
-
-        SslContextFactory.ClientAuth clientAuth = 
getClientAuthStatus(sslSocket);
-        logger.debug("SSL Socket client auth status: {}", clientAuth);
-
-        if (clientAuth != SslContextFactory.ClientAuth.NONE) {
-            try {
-                final Certificate[] certChains = 
sslSocket.getSession().getPeerCertificates();
-                if (certChains != null && certChains.length > 0) {
-                    X509Certificate x509Certificate = 
convertAbstractX509Certificate(certChains[0]);
-                    dn = x509Certificate.getSubjectDN().getName().trim();
-                    logger.debug("Extracted DN={} from client certificate", 
dn);
-                }
-            } catch (SSLPeerUnverifiedException e) {
-                if (e.getMessage().equals(PEER_NOT_AUTHENTICATED_MSG)) {
-                    logger.error("The incoming request did not contain client 
certificates and thus the DN cannot" +
-                            " be extracted. Check that the other endpoint is 
providing a complete client certificate chain");
-                }
-                if (clientAuth == SslContextFactory.ClientAuth.WANT) {
-                    logger.warn("Suppressing missing client certificate 
exception because client auth is set to 'want'");
-                    return dn;
-                }
-                throw new CertificateException(e);
-            }
-        }
-        return dn;
-    }
-
-    /**
-     * Returns the DN extracted from the server certificate.
-     *
-     * @param socket the SSL Socket
-     * @return the extracted DN
-     * @throws CertificateException if there is a problem parsing the 
certificate
-     */
-    private static String extractPeerDNFromServerSSLSocket(Socket socket) 
throws CertificateException {
-        String dn = null;
-        if (socket instanceof SSLSocket) {
-            final SSLSocket sslSocket = (SSLSocket) socket;
-            try {
-                final Certificate[] certChains = 
sslSocket.getSession().getPeerCertificates();
-                if (certChains != null && certChains.length > 0) {
-                    X509Certificate x509Certificate = 
convertAbstractX509Certificate(certChains[0]);
-                    dn = x509Certificate.getSubjectDN().getName().trim();
-                    logger.debug("Extracted DN={} from server certificate", 
dn);
-                }
-            } catch (SSLPeerUnverifiedException e) {
-                if (e.getMessage().equals(PEER_NOT_AUTHENTICATED_MSG)) {
-                    logger.error("The server did not present a certificate and 
thus the DN cannot" +
-                            " be extracted. Check that the other endpoint is 
providing a complete certificate chain");
-                }
-                throw new CertificateException(e);
-            }
-        }
-        return dn;
-    }
-
-    private static SslContextFactory.ClientAuth getClientAuthStatus(SSLSocket 
sslSocket) {
-        return sslSocket.getNeedClientAuth() ? 
SslContextFactory.ClientAuth.REQUIRED : sslSocket.getWantClientAuth() ? 
SslContextFactory.ClientAuth.WANT : SslContextFactory.ClientAuth.NONE;
-    }
-
-    /**
-     * Accepts a legacy {@link javax.security.cert.X509Certificate} and 
returns an {@link X509Certificate}. The {@code javax.*} package certificate 
classes are for legacy compatibility and should
-     * not be used for new development.
-     *
-     * @param legacyCertificate the {@code javax.security.cert.X509Certificate}
-     * @return a new {@code java.security.cert.X509Certificate}
-     * @throws CertificateException if there is an error generating the new 
certificate
-     */
-    @SuppressWarnings("deprecation")
-    public static X509Certificate 
convertLegacyX509Certificate(javax.security.cert.X509Certificate 
legacyCertificate) throws CertificateException {
-        if (legacyCertificate == null) {
-            throw new IllegalArgumentException("The X.509 certificate cannot 
be null");
-        }
-
-        try {
-            return formX509Certificate(legacyCertificate.getEncoded());
-        } catch (javax.security.cert.CertificateEncodingException e) {
-            throw new CertificateException(e);
-        }
-    }
-
-    /**
-     * Accepts an abstract {@link java.security.cert.Certificate} and returns 
an {@link X509Certificate}. Because {@code 
sslSocket.getSession().getPeerCertificates()} returns an array of the
-     * abstract certificates, they must be translated to X.509 to replace the 
functionality of {@code sslSocket.getSession().getPeerCertificateChain()}.
-     *
-     * @param abstractCertificate the {@code java.security.cert.Certificate}
-     * @return a new {@code java.security.cert.X509Certificate}
-     * @throws CertificateException if there is an error generating the new 
certificate
-     */
-    public static X509Certificate 
convertAbstractX509Certificate(java.security.cert.Certificate 
abstractCertificate) throws CertificateException {
-        if (abstractCertificate == null || !(abstractCertificate instanceof 
X509Certificate)) {
-            throw new IllegalArgumentException("The certificate cannot be null 
and must be an X.509 certificate");
-        }
-
-        try {
-            return formX509Certificate(abstractCertificate.getEncoded());
-        } catch (java.security.cert.CertificateEncodingException e) {
-            throw new CertificateException(e);
-        }
-    }
-
-    private static X509Certificate formX509Certificate(byte[] 
encodedCertificate) throws CertificateException {
-        try {
-            CertificateFactory cf = CertificateFactory.getInstance("X.509");
-            ByteArrayInputStream bais = new 
ByteArrayInputStream(encodedCertificate);
-            return (X509Certificate) cf.generateCertificate(bais);
-        } catch (CertificateException e) {
-            logger.error("Error converting the certificate", e);
-            throw e;
-        }
-    }
-
-    /**
-     * Reorders DN to the order the elements appear in the RFC 2253 table
-     * <p>
-     * https://www.ietf.org/rfc/rfc2253.txt
-     * <p>
-     * String  X.500 AttributeType
-     * ------------------------------
-     * CN      commonName
-     * L       localityName
-     * ST      stateOrProvinceName
-     * O       organizationName
-     * OU      organizationalUnitName
-     * C       countryName
-     * STREET  streetAddress
-     * DC      domainComponent
-     * UID     userid
-     *
-     * @param dn a possibly unordered DN
-     * @return the ordered dn
-     */
-    public static String reorderDn(String dn) {
-        RDN[] rdNs = new X500Name(dn).getRDNs();
-        Arrays.sort(rdNs, new Comparator<RDN>() {
-            @Override
-            public int compare(RDN o1, RDN o2) {
-                AttributeTypeAndValue o1First = o1.getFirst();
-                AttributeTypeAndValue o2First = o2.getFirst();
-
-                ASN1ObjectIdentifier o1Type = o1First.getType();
-                ASN1ObjectIdentifier o2Type = o2First.getType();
-
-                Integer o1Rank = dnOrderMap.get(o1Type);
-                Integer o2Rank = dnOrderMap.get(o2Type);
-                if (o1Rank == null) {
-                    if (o2Rank == null) {
-                        int idComparison = 
o1Type.getId().compareTo(o2Type.getId());
-                        if (idComparison != 0) {
-                            return idComparison;
-                        }
-                        return 
String.valueOf(o1Type).compareTo(String.valueOf(o2Type));
-                    }
-                    return 1;
-                } else if (o2Rank == null) {
-                    return -1;
-                }
-                return o1Rank - o2Rank;
-            }
-        });
-        return new X500Name(rdNs).toString();
-    }
-
-    /**
-     * Reverses the X500Name in order make the certificate be in the right 
order
-     * [see 
http://stackoverflow.com/questions/7567837/attributes-reversed-in-certificate-subject-and-issuer/12645265]
-     *
-     * @param x500Name the X500Name created with the intended order
-     * @return the X500Name reversed
-     */
-    private static X500Name reverseX500Name(X500Name x500Name) {
-        List<RDN> rdns = Arrays.asList(x500Name.getRDNs());
-        Collections.reverse(rdns);
-        return new X500Name(rdns.toArray(new RDN[rdns.size()]));
-    }
-
-    /**
-     * Generates a unique serial number by using the current time in 
milliseconds left shifted 32 bits (to make room for incrementor) with an 
incrementor added
-     *
-     * @return a unique serial number (technically unique to this classloader)
-     */
-    protected static synchronized BigInteger getUniqueSerialNumber() {
-        final long currentTimeMillis = System.currentTimeMillis();
-        final int incrementorValue;
-
-        if (lastSerialNumberMillis != currentTimeMillis) {
-            // We can only get into this block once per millisecond
-            millisecondBigInteger = 
BigInteger.valueOf(currentTimeMillis).shiftLeft(32);
-            lastSerialNumberMillis = currentTimeMillis;
-            incrementorValue = 0;
-            serialNumberIncrementor = 1;
-        } else {
-            // Already created at least one serial number this millisecond
-            incrementorValue = serialNumberIncrementor++;
-        }
-
-        return millisecondBigInteger.add(BigInteger.valueOf(incrementorValue));
-    }
-
-    /**
-     * Generates a self-signed {@link X509Certificate} suitable for use as a 
Certificate Authority.
-     *
-     * @param keyPair                 the {@link KeyPair} to generate the 
{@link X509Certificate} for
-     * @param dn                      the distinguished name to user for the 
{@link X509Certificate}
-     * @param signingAlgorithm        the signing algorithm to use for the 
{@link X509Certificate}
-     * @param certificateDurationDays the duration in days for which the 
{@link X509Certificate} should be valid
-     * @return a self-signed {@link X509Certificate} suitable for use as a 
Certificate Authority
-     * @throws CertificateException if there is an generating the new 
certificate
-     */
-    public static X509Certificate generateSelfSignedX509Certificate(KeyPair 
keyPair, String dn, String signingAlgorithm, int certificateDurationDays)
-            throws CertificateException {
-        try {
-            ContentSigner sigGen = new 
JcaContentSignerBuilder(signingAlgorithm).setProvider(BouncyCastleProvider.PROVIDER_NAME).build(keyPair.getPrivate());
-            SubjectPublicKeyInfo subPubKeyInfo = 
SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded());
-            Date startDate = new Date();
-            Date endDate = new Date(startDate.getTime() + 
TimeUnit.DAYS.toMillis(certificateDurationDays));
-
-            X509v3CertificateBuilder certBuilder = new 
X509v3CertificateBuilder(
-                    reverseX500Name(new X500Name(dn)),
-                    getUniqueSerialNumber(),
-                    startDate, endDate,
-                    reverseX500Name(new X500Name(dn)),
-                    subPubKeyInfo);
-
-            // Set certificate extensions
-            // (1) digitalSignature extension
-            certBuilder.addExtension(Extension.keyUsage, true, new 
KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment | 
KeyUsage.dataEncipherment
-                    | KeyUsage.keyAgreement | KeyUsage.nonRepudiation | 
KeyUsage.cRLSign | KeyUsage.keyCertSign));
-
-            certBuilder.addExtension(Extension.basicConstraints, false, new 
BasicConstraints(true));
-
-            certBuilder.addExtension(Extension.subjectKeyIdentifier, false, 
new JcaX509ExtensionUtils().createSubjectKeyIdentifier(keyPair.getPublic()));
-
-            certBuilder.addExtension(Extension.authorityKeyIdentifier, false, 
new JcaX509ExtensionUtils().createAuthorityKeyIdentifier(keyPair.getPublic()));
-
-            // (2) extendedKeyUsage extension
-            certBuilder.addExtension(Extension.extendedKeyUsage, false, new 
ExtendedKeyUsage(new KeyPurposeId[]{KeyPurposeId.id_kp_clientAuth, 
KeyPurposeId.id_kp_serverAuth}));
-
-            // Sign the certificate
-            X509CertificateHolder certificateHolder = 
certBuilder.build(sigGen);
-            return new 
JcaX509CertificateConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME).getCertificate(certificateHolder);
-        } catch (CertIOException | NoSuchAlgorithmException | 
OperatorCreationException e) {
-            throw new CertificateException(e);
-        }
-    }
-
-    /**
-     * Generates an issued {@link X509Certificate} from the given issuer 
certificate and {@link KeyPair}
-     *
-     * @param dn               the distinguished name to use
-     * @param publicKey        the public key to issue the certificate to
-     * @param issuer           the issuer's certificate
-     * @param issuerKeyPair    the issuer's keypair
-     * @param signingAlgorithm the signing algorithm to use
-     * @param days             the number of days it should be valid for
-     * @return an issued {@link X509Certificate} from the given issuer 
certificate and {@link KeyPair}
-     * @throws CertificateException if there is an error issuing the 
certificate
-     */
-    public static X509Certificate generateIssuedCertificate(String dn, 
PublicKey publicKey, X509Certificate issuer, KeyPair issuerKeyPair, String 
signingAlgorithm, int days)
-            throws CertificateException {
-        return generateIssuedCertificate(dn, publicKey, null, issuer, 
issuerKeyPair, signingAlgorithm, days);
-    }
-
-    /**
-     * Generates an issued {@link X509Certificate} from the given issuer 
certificate and {@link KeyPair}
-     *
-     * @param dn               the distinguished name to use
-     * @param publicKey        the public key to issue the certificate to
-     * @param extensions       extensions extracted from the CSR
-     * @param issuer           the issuer's certificate
-     * @param issuerKeyPair    the issuer's keypair
-     * @param signingAlgorithm the signing algorithm to use
-     * @param days             the number of days it should be valid for
-     * @return an issued {@link X509Certificate} from the given issuer 
certificate and {@link KeyPair}
-     * @throws CertificateException if there is an error issuing the 
certificate
-     */
-    public static X509Certificate generateIssuedCertificate(String dn, 
PublicKey publicKey, Extensions extensions, X509Certificate issuer, KeyPair 
issuerKeyPair, String signingAlgorithm, int days)
-            throws CertificateException {
-        try {
-            ContentSigner sigGen = new 
JcaContentSignerBuilder(signingAlgorithm).setProvider(BouncyCastleProvider.PROVIDER_NAME).build(issuerKeyPair.getPrivate());
-            SubjectPublicKeyInfo subPubKeyInfo = 
SubjectPublicKeyInfo.getInstance(publicKey.getEncoded());
-            Date startDate = new Date();
-            Date endDate = new Date(startDate.getTime() + 
TimeUnit.DAYS.toMillis(days));
-
-            X509v3CertificateBuilder certBuilder = new 
X509v3CertificateBuilder(
-                    reverseX500Name(new 
X500Name(issuer.getSubjectX500Principal().getName())),
-                    getUniqueSerialNumber(),
-                    startDate, endDate,
-                    reverseX500Name(new X500Name(dn)),
-                    subPubKeyInfo);
-
-            certBuilder.addExtension(Extension.subjectKeyIdentifier, false, 
new JcaX509ExtensionUtils().createSubjectKeyIdentifier(publicKey));
-
-            certBuilder.addExtension(Extension.authorityKeyIdentifier, false, 
new 
JcaX509ExtensionUtils().createAuthorityKeyIdentifier(issuerKeyPair.getPublic()));
-            // Set certificate extensions
-            // (1) digitalSignature extension
-            certBuilder.addExtension(Extension.keyUsage, true,
-                    new KeyUsage(KeyUsage.digitalSignature | 
KeyUsage.keyEncipherment | KeyUsage.dataEncipherment | KeyUsage.keyAgreement | 
KeyUsage.nonRepudiation));
-
-            certBuilder.addExtension(Extension.basicConstraints, false, new 
BasicConstraints(false));
-
-            // (2) extendedKeyUsage extension
-            certBuilder.addExtension(Extension.extendedKeyUsage, false, new 
ExtendedKeyUsage(new KeyPurposeId[]{KeyPurposeId.id_kp_clientAuth, 
KeyPurposeId.id_kp_serverAuth}));
-
-            // (3) subjectAlternativeName
-            if (extensions != null && 
extensions.getExtension(Extension.subjectAlternativeName) != null) {
-                certBuilder.addExtension(Extension.subjectAlternativeName, 
false, extensions.getExtensionParsedValue(Extension.subjectAlternativeName));
-            }
-
-            X509CertificateHolder certificateHolder = 
certBuilder.build(sigGen);
-            return new 
JcaX509CertificateConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME).getCertificate(certificateHolder);
-        } catch (CertIOException | NoSuchAlgorithmException | 
OperatorCreationException e) {
-            throw new CertificateException(e);
-        }
-    }
-
-    /**
-     * Returns true if the two provided DNs are equivalent, regardless of the 
order of the elements. Returns false if one or both are invalid DNs.
-     * <p>
-     * Example:
-     * <p>
-     * CN=test1, O=testOrg, C=US compared to CN=test1, O=testOrg, C=US -> true
-     * CN=test1, O=testOrg, C=US compared to O=testOrg, CN=test1, C=US -> true
-     * CN=test1, O=testOrg, C=US compared to CN=test2, O=testOrg, C=US -> false
-     * CN=test1, O=testOrg, C=US compared to O=testOrg, CN=test2, C=US -> false
-     * CN=test1, O=testOrg, C=US compared to                           -> false
-     * compared to                           -> true
-     *
-     * @param dn1 the first DN to compare
-     * @param dn2 the second DN to compare
-     * @return true if the DNs are equivalent, false otherwise
-     */
-    public static boolean compareDNs(String dn1, String dn2) {
-        if (dn1 == null) {
-            dn1 = "";
-        }
-
-        if (dn2 == null) {
-            dn2 = "";
-        }
-
-        if (StringUtils.isEmpty(dn1) || StringUtils.isEmpty(dn2)) {
-            return dn1.equals(dn2);
-        }
-        try {
-            List<Rdn> rdn1 = new LdapName(dn1).getRdns();
-            List<Rdn> rdn2 = new LdapName(dn2).getRdns();
-
-            return rdn1.size() == rdn2.size() && rdn1.containsAll(rdn2);
-        } catch (InvalidNameException e) {
-            logger.warn("Cannot compare DNs: {} and {} because one or both is 
not a valid DN", dn1, dn2);
-            return false;
-        }
-    }
-
-    /**
-     * Extract extensions from CSR object
-     */
-    public static Extensions 
getExtensionsFromCSR(JcaPKCS10CertificationRequest csr) {
-        Attribute[] attributess = 
csr.getAttributes(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest);
-        for (Attribute attribute : attributess) {
-            ASN1Set attValue = attribute.getAttrValues();
-            if (attValue != null) {
-                ASN1Encodable extension = attValue.getObjectAt(0);
-                if (extension instanceof Extensions) {
-                    return (Extensions) extension;
-                } else if (extension instanceof DERSequence) {
-                    return Extensions.getInstance(extension);
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns the JVM Java major version based on the System properties (e.g. 
{@code JVM 1.8.0.231} -> {code 8}).
-     *
-     * @return the Java major version
-     */
-    public static int getJavaVersion() {
-        String version = System.getProperty("java.version");
-        return parseJavaVersion(version);
-    }
-
-    /**
-     * Returns the major version parsed from the provided Java version string 
(e.g. {@code "1.8.0.231"} -> {@code 8}).
-     *
-     * @param version the Java version string
-     * @return the major version as an int
-     */
-    public static int parseJavaVersion(String version) {
-        String majorVersion;
-        if (version.startsWith("1.")) {
-            majorVersion = version.substring(2, 3);
-        } else {
-            Pattern majorVersion9PlusPattern = Pattern.compile("(\\d+).*");
-            Matcher m = majorVersion9PlusPattern.matcher(version);
-            if (m.find()) {
-                majorVersion = m.group(1);
-            } else {
-                throw new IllegalArgumentException("Could not detect major 
version of " + version);
-            }
-        }
-        return Integer.parseInt(majorVersion);
-    }
-
-    /**
-     * Returns a {@code String[]} of supported TLS protocol versions based on 
the current Java platform version.
-     *
-     * @return the supported TLS protocol version(s)
-     */
-    public static String[] getCurrentSupportedTlsProtocolVersions() {
-        int javaMajorVersion = getJavaVersion();
-        if (javaMajorVersion < 11) {
-            return JAVA_8_SUPPORTED_TLS_PROTOCOL_VERSIONS;
-        } else {
-            return JAVA_11_SUPPORTED_TLS_PROTOCOL_VERSIONS;
-        }
-    }
-
-    /**
-     * Returns the highest supported TLS protocol version based on the current 
Java platform version.
-     *
-     * @return the TLS protocol (e.g. {@code "TLSv1.2"})
-     */
-    public static String getHighestCurrentSupportedTlsProtocolVersion() {
-        int javaMajorVersion = getJavaVersion();
-        if (javaMajorVersion < 11) {
-            return JAVA_8_MAX_SUPPORTED_TLS_PROTOCOL_VERSION;
-        } else {
-            return JAVA_11_MAX_SUPPORTED_TLS_PROTOCOL_VERSION;
-        }
-    }
-
-    private CertificateUtils() {
-    }
-}
diff --git 
a/nifi-registry/nifi-registry-core/nifi-registry-security-utils/src/main/java/org/apache/nifi/registry/security/util/SslContextFactory.java
 
b/nifi-registry/nifi-registry-core/nifi-registry-security-utils/src/main/java/org/apache/nifi/registry/security/util/SslContextFactory.java
deleted file mode 100644
index e10749951b..0000000000
--- 
a/nifi-registry/nifi-registry-core/nifi-registry-security-utils/src/main/java/org/apache/nifi/registry/security/util/SslContextFactory.java
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.registry.security.util;
-
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.KeyManagementException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.CertificateException;
-
-/**
- * A factory for creating SSL contexts using the application's security
- * properties.
- *
- */
-public final class SslContextFactory {
-
-    public static enum ClientAuth {
-
-        WANT,
-        REQUIRED,
-        NONE
-    }
-
-    /**
-     * Creates a SSLContext instance using the given information. The password 
for the key is assumed to be the same
-     * as the password for the keystore. If this is not the case, the {@link 
#createSslContext(String, char[], chart[], String, String, char[], String, 
ClientAuth, String)}
-     * method should be used instead
-     *
-     * @param keystore the full path to the keystore
-     * @param keystorePasswd the keystore password
-     * @param keystoreType the type of keystore (e.g., PKCS12, JKS)
-     * @param truststore the full path to the truststore
-     * @param truststorePasswd the truststore password
-     * @param truststoreType the type of truststore (e.g., PKCS12, JKS)
-     * @param clientAuth the type of client authentication
-     * @param protocol         the protocol to use for the SSL connection
-     *
-     * @return a SSLContext instance
-     * @throws KeyStoreException if any issues accessing the keystore
-     * @throws IOException for any problems loading the keystores
-     * @throws NoSuchAlgorithmException if an algorithm is found to be used 
but is unknown
-     * @throws CertificateException if there is an issue with the certificate
-     * @throws UnrecoverableKeyException if the key is insufficient
-     * @throws KeyManagementException if unable to manage the key
-     */
-    public static SSLContext createSslContext(
-            final String keystore, final char[] keystorePasswd, final String 
keystoreType,
-            final String truststore, final char[] truststorePasswd, final 
String truststoreType,
-            final ClientAuth clientAuth, final String protocol)
-            throws KeyStoreException, IOException, NoSuchAlgorithmException, 
CertificateException,
-            UnrecoverableKeyException, KeyManagementException {
-
-        // Pass the keystore password as both the keystore password and the 
key password.
-        return createSslContext(keystore, keystorePasswd, keystorePasswd, 
keystoreType, truststore, truststorePasswd, truststoreType, clientAuth, 
protocol);
-    }
-
-    /**
-     * Creates a SSLContext instance using the given information.
-     *
-     * @param keystore the full path to the keystore
-     * @param keystorePasswd the keystore password
-     * @param keystoreType the type of keystore (e.g., PKCS12, JKS)
-     * @param truststore the full path to the truststore
-     * @param truststorePasswd the truststore password
-     * @param truststoreType the type of truststore (e.g., PKCS12, JKS)
-     * @param clientAuth the type of client authentication
-     * @param protocol         the protocol to use for the SSL connection
-     *
-     * @return a SSLContext instance
-     * @throws KeyStoreException if any issues accessing the keystore
-     * @throws IOException for any problems loading the keystores
-     * @throws NoSuchAlgorithmException if an algorithm is found to be used 
but is unknown
-     * @throws CertificateException if there is an issue with the certificate
-     * @throws UnrecoverableKeyException if the key is insufficient
-     * @throws KeyManagementException if unable to manage the key
-     */
-    public static SSLContext createSslContext(
-            final String keystore, final char[] keystorePasswd, final char[] 
keyPasswd, final String keystoreType,
-            final String truststore, final char[] truststorePasswd, final 
String truststoreType,
-            final ClientAuth clientAuth, final String protocol)
-            throws KeyStoreException, IOException, NoSuchAlgorithmException, 
CertificateException,
-            UnrecoverableKeyException, KeyManagementException {
-
-        // prepare the keystore
-        final KeyStore keyStore = KeyStoreUtils.getKeyStore(keystoreType);
-        try (final InputStream keyStoreStream = new FileInputStream(keystore)) 
{
-            keyStore.load(keyStoreStream, keystorePasswd);
-        }
-        final KeyManagerFactory keyManagerFactory = 
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
-        if (keyPasswd == null) {
-            keyManagerFactory.init(keyStore, keystorePasswd);
-        } else {
-            keyManagerFactory.init(keyStore, keyPasswd);
-        }
-
-        // prepare the truststore
-        final KeyStore trustStore = KeyStoreUtils.getKeyStore(truststoreType);
-        try (final InputStream trustStoreStream = new 
FileInputStream(truststore)) {
-            trustStore.load(trustStoreStream, truststorePasswd);
-        }
-        final TrustManagerFactory trustManagerFactory = 
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
-        trustManagerFactory.init(trustStore);
-
-        // initialize the ssl context
-        final SSLContext sslContext = SSLContext.getInstance(protocol);
-        sslContext.init(keyManagerFactory.getKeyManagers(), 
trustManagerFactory.getTrustManagers(), new SecureRandom());
-        if (ClientAuth.REQUIRED == clientAuth) {
-            sslContext.getDefaultSSLParameters().setNeedClientAuth(true);
-        } else if (ClientAuth.WANT == clientAuth) {
-            sslContext.getDefaultSSLParameters().setWantClientAuth(true);
-        } else {
-            sslContext.getDefaultSSLParameters().setWantClientAuth(false);
-        }
-
-        return sslContext;
-
-    }
-
-    /**
-     * Creates a SSLContext instance using the given information. This method 
assumes that the key password is
-     * the same as the keystore password. If this is not the case, use the 
{@link #createSslContext(String, char[], char[], String, String)}
-     * method instead.
-     *
-     * @param keystore the full path to the keystore
-     * @param keystorePasswd the keystore password
-     * @param keystoreType the type of keystore (e.g., PKCS12, JKS)
-     * @param protocol the protocol to use for the SSL connection
-     *
-     * @return a SSLContext instance
-     * @throws KeyStoreException if any issues accessing the keystore
-     * @throws IOException for any problems loading the keystores
-     * @throws NoSuchAlgorithmException if an algorithm is found to be used 
but is unknown
-     * @throws CertificateException if there is an issue with the certificate
-     * @throws UnrecoverableKeyException if the key is insufficient
-     * @throws KeyManagementException if unable to manage the key
-     */
-    public static SSLContext createSslContext(
-        final String keystore, final char[] keystorePasswd, final String 
keystoreType, final String protocol)
-        throws KeyStoreException, IOException, NoSuchAlgorithmException, 
CertificateException,
-        UnrecoverableKeyException, KeyManagementException {
-
-        // create SSL Context passing keystore password as the key password
-        return createSslContext(keystore, keystorePasswd, keystorePasswd, 
keystoreType, protocol);
-    }
-
-    /**
-     * Creates a SSLContext instance using the given information.
-     *
-     * @param keystore the full path to the keystore
-     * @param keystorePasswd the keystore password
-     * @param keystoreType the type of keystore (e.g., PKCS12, JKS)
-     * @param protocol the protocol to use for the SSL connection
-     *
-     * @return a SSLContext instance
-     * @throws KeyStoreException if any issues accessing the keystore
-     * @throws IOException for any problems loading the keystores
-     * @throws NoSuchAlgorithmException if an algorithm is found to be used 
but is unknown
-     * @throws CertificateException if there is an issue with the certificate
-     * @throws UnrecoverableKeyException if the key is insufficient
-     * @throws KeyManagementException if unable to manage the key
-     */
-    public static SSLContext createSslContext(
-        final String keystore, final char[] keystorePasswd, final char[] 
keyPasswd, final String keystoreType, final String protocol)
-            throws KeyStoreException, IOException, NoSuchAlgorithmException, 
CertificateException,
-            UnrecoverableKeyException, KeyManagementException {
-
-        // prepare the keystore
-        final KeyStore keyStore = KeyStoreUtils.getKeyStore(keystoreType);
-        try (final InputStream keyStoreStream = new FileInputStream(keystore)) 
{
-            keyStore.load(keyStoreStream, keystorePasswd);
-        }
-        final KeyManagerFactory keyManagerFactory = 
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
-        if (keyPasswd == null) {
-            keyManagerFactory.init(keyStore, keystorePasswd);
-        } else {
-            keyManagerFactory.init(keyStore, keyPasswd);
-        }
-
-        // initialize the ssl context
-        final SSLContext ctx = SSLContext.getInstance(protocol);
-        ctx.init(keyManagerFactory.getKeyManagers(), new TrustManager[0], new 
SecureRandom());
-
-        return ctx;
-
-    }
-
-    /**
-     * Creates a SSLContext instance using the given information.
-     *
-     * @param truststore the full path to the truststore
-     * @param truststorePasswd the truststore password
-     * @param truststoreType the type of truststore (e.g., PKCS12, JKS)
-     * @param protocol the protocol to use for the SSL connection
-     *
-     * @return a SSLContext instance
-     * @throws KeyStoreException if any issues accessing the keystore
-     * @throws IOException for any problems loading the keystores
-     * @throws NoSuchAlgorithmException if an algorithm is found to be used 
but is unknown
-     * @throws CertificateException if there is an issue with the certificate
-     * @throws UnrecoverableKeyException if the key is insufficient
-     * @throws KeyManagementException if unable to manage the key
-     */
-    public static SSLContext createTrustSslContext(
-            final String truststore, final char[] truststorePasswd, final 
String truststoreType, final String protocol)
-            throws KeyStoreException, IOException, NoSuchAlgorithmException, 
CertificateException,
-            UnrecoverableKeyException, KeyManagementException {
-
-        // prepare the truststore
-        final KeyStore trustStore = KeyStoreUtils.getKeyStore(truststoreType);
-        try (final InputStream trustStoreStream = new 
FileInputStream(truststore)) {
-            trustStore.load(trustStoreStream, truststorePasswd);
-        }
-        final TrustManagerFactory trustManagerFactory = 
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
-        trustManagerFactory.init(trustStore);
-
-        // initialize the ssl context
-        final SSLContext ctx = SSLContext.getInstance(protocol);
-        ctx.init(new KeyManager[0], trustManagerFactory.getTrustManagers(), 
new SecureRandom());
-
-        return ctx;
-
-    }
-
-}
diff --git a/nifi-toolkit/nifi-toolkit-admin/pom.xml 
b/nifi-toolkit/nifi-toolkit-admin/pom.xml
index d99c48dc8b..6d33c2f723 100644
--- a/nifi-toolkit/nifi-toolkit-admin/pom.xml
+++ b/nifi-toolkit/nifi-toolkit-admin/pom.xml
@@ -21,6 +21,11 @@ language governing permissions and limitations under the 
License. -->
     <artifactId>nifi-toolkit-admin</artifactId>
 
     <dependencies>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-security-ssl</artifactId>
+            <version>1.19.0-SNAPSHOT</version>
+        </dependency>
         <dependency>
             <groupId>commons-beanutils</groupId>
             <artifactId>commons-beanutils</artifactId>
diff --git 
a/nifi-toolkit/nifi-toolkit-admin/src/main/groovy/org/apache/nifi/toolkit/admin/client/NiFiClientFactory.groovy
 
b/nifi-toolkit/nifi-toolkit-admin/src/main/groovy/org/apache/nifi/toolkit/admin/client/NiFiClientFactory.groovy
index 27f75c28a1..44ae51ef83 100644
--- 
a/nifi-toolkit/nifi-toolkit-admin/src/main/groovy/org/apache/nifi/toolkit/admin/client/NiFiClientFactory.groovy
+++ 
b/nifi-toolkit/nifi-toolkit-admin/src/main/groovy/org/apache/nifi/toolkit/admin/client/NiFiClientFactory.groovy
@@ -18,42 +18,38 @@ package org.apache.nifi.toolkit.admin.client
 
 import org.apache.commons.lang3.StringUtils
 import org.apache.http.conn.ssl.DefaultHostnameVerifier
+import org.apache.nifi.security.ssl.StandardKeyStoreBuilder
+import org.apache.nifi.security.ssl.StandardSslContextBuilder
 import org.apache.nifi.util.NiFiProperties
-import org.slf4j.Logger
-import org.slf4j.LoggerFactory
 
-import javax.net.ssl.KeyManagerFactory
 import javax.net.ssl.SSLContext
-import javax.net.ssl.TrustManagerFactory
 import javax.ws.rs.client.Client
 import javax.ws.rs.client.ClientBuilder
 import java.security.KeyManagementException
 import java.security.KeyStore
 import java.security.KeyStoreException
 import java.security.NoSuchAlgorithmException
-import java.security.SecureRandom
 import java.security.UnrecoverableKeyException
 import java.security.cert.CertificateException
 
 class NiFiClientFactory implements ClientFactory{
 
-    private static final Logger logger = 
LoggerFactory.getLogger(NiFiClientFactory.class)
     static enum NiFiAuthType{ NONE, SSL }
 
-    public Client getClient(NiFiProperties niFiProperties, String 
nifiInstallDir) throws Exception {
+    Client getClient(NiFiProperties niFiProperties, String nifiInstallDir) 
throws Exception {
 
-        final String authTypeStr = 
StringUtils.isEmpty(niFiProperties.getProperty(NiFiProperties.WEB_HTTPS_HOST)) 
&&  
StringUtils.isEmpty(niFiProperties.getProperty(NiFiProperties.WEB_HTTPS_PORT))  
? NiFiAuthType.NONE : NiFiAuthType.SSL;
-        final NiFiAuthType authType = NiFiAuthType.valueOf(authTypeStr);
+        final String authTypeStr = 
StringUtils.isEmpty(niFiProperties.getProperty(NiFiProperties.WEB_HTTPS_HOST)) 
&&  
StringUtils.isEmpty(niFiProperties.getProperty(NiFiProperties.WEB_HTTPS_PORT))  
? NiFiAuthType.NONE : NiFiAuthType.SSL
+        final NiFiAuthType authType = NiFiAuthType.valueOf(authTypeStr)
 
-        SSLContext sslContext = null;
+        SSLContext sslContext = null
 
-        if (NiFiAuthType.SSL.equals(authType)) {
-            String keystore = 
niFiProperties.getProperty(NiFiProperties.SECURITY_KEYSTORE);
-            final String keystoreType = 
niFiProperties.getProperty(NiFiProperties.SECURITY_KEYSTORE_TYPE);
-            final String keystorePassword = 
niFiProperties.getProperty(NiFiProperties.SECURITY_KEYSTORE_PASSWD);
-            String truststore = 
niFiProperties.getProperty(NiFiProperties.SECURITY_TRUSTSTORE);
-            final String truststoreType = 
niFiProperties.getProperty(NiFiProperties.SECURITY_TRUSTSTORE_TYPE);
-            final String truststorePassword = 
niFiProperties.getProperty(NiFiProperties.SECURITY_TRUSTSTORE_PASSWD);
+        if (NiFiAuthType.SSL == authType) {
+            String keystore = 
niFiProperties.getProperty(NiFiProperties.SECURITY_KEYSTORE)
+            final String keystoreType = 
niFiProperties.getProperty(NiFiProperties.SECURITY_KEYSTORE_TYPE)
+            final String keystorePassword = 
niFiProperties.getProperty(NiFiProperties.SECURITY_KEYSTORE_PASSWD)
+            String truststore = 
niFiProperties.getProperty(NiFiProperties.SECURITY_TRUSTSTORE)
+            final String truststoreType = 
niFiProperties.getProperty(NiFiProperties.SECURITY_TRUSTSTORE_TYPE)
+            final String truststorePassword = 
niFiProperties.getProperty(NiFiProperties.SECURITY_TRUSTSTORE_PASSWD)
 
             if(keystore.startsWith("./")){
                 keystore = keystore.replace("./",nifiInstallDir+"/")
@@ -69,16 +65,16 @@ class NiFiClientFactory implements ClientFactory{
                     truststore.trim(),
                     truststorePassword.trim().toCharArray(),
                     truststoreType.trim(),
-                    "TLS");
+                    "TLS")
         }
 
-        final ClientBuilder clientBuilder = ClientBuilder.newBuilder();
+        final ClientBuilder clientBuilder = ClientBuilder.newBuilder()
 
         if (sslContext != null) {
-            clientBuilder.sslContext(sslContext).hostnameVerifier(new 
DefaultHostnameVerifier());
+            clientBuilder.sslContext(sslContext).hostnameVerifier(new 
DefaultHostnameVerifier())
         }
 
-        return clientBuilder.build();
+        return clientBuilder.build()
 
     }
 
@@ -89,29 +85,29 @@ class NiFiClientFactory implements ClientFactory{
             throws KeyStoreException, IOException, NoSuchAlgorithmException, 
CertificateException,
                     UnrecoverableKeyException, KeyManagementException {
 
-        // prepare the keystore
-        final KeyStore keyStore = KeyStore.getInstance(keystoreType);
-        final InputStream keyStoreStream = new FileInputStream(keystore)
-            keyStore.load(keyStoreStream, keystorePasswd);
-
-
-        final KeyManagerFactory keyManagerFactory = 
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
-        keyManagerFactory.init(keyStore, keystorePasswd);
-
-        // prepare the truststore
-        final KeyStore trustStore = KeyStore.getInstance(truststoreType);
-        final InputStream trustStoreStream = new FileInputStream(truststore)
-        trustStore.load(trustStoreStream, truststorePasswd);
+        final KeyStore keyStore
+        try (final InputStream keyStoreStream = new FileInputStream(keystore)) 
{
+            keyStore = new StandardKeyStoreBuilder()
+                    .inputStream(keyStoreStream)
+                    .password(keystorePasswd)
+                    .type(keystoreType)
+                    .build()
+        }
 
-        final TrustManagerFactory trustManagerFactory = 
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
-        trustManagerFactory.init(trustStore);
+        final KeyStore trustStore
+        try (final InputStream trustStoreStream = new 
FileInputStream(truststore)) {
+            trustStore = new StandardKeyStoreBuilder()
+                    .inputStream(trustStoreStream)
+                    .password(truststorePasswd)
+                    .type(truststoreType)
+                    .build()
+        }
 
-        // initialize the ssl context
-        final SSLContext sslContext = SSLContext.getInstance(protocol);
-        sslContext.init(keyManagerFactory.getKeyManagers(), 
trustManagerFactory.getTrustManagers(), new SecureRandom());
-        return sslContext;
+        return new StandardSslContextBuilder()
+                .keyPassword(keystorePasswd)
+                .keyStore(keyStore)
+                .trustStore(trustStore)
+                .protocol(protocol)
+                .build()
     }
-
-
-
 }
diff --git a/nifi-toolkit/nifi-toolkit-cli/pom.xml 
b/nifi-toolkit/nifi-toolkit-cli/pom.xml
index ffc8052dc1..16acb74f93 100644
--- a/nifi-toolkit/nifi-toolkit-cli/pom.xml
+++ b/nifi-toolkit/nifi-toolkit-cli/pom.xml
@@ -49,6 +49,11 @@
     </build>
 
     <dependencies>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-security-ssl</artifactId>
+            <version>1.19.0-SNAPSHOT</version>
+        </dependency>
         <dependency>
             <groupId>commons-cli</groupId>
             <artifactId>commons-cli</artifactId>
diff --git 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/nifi/NiFiClientConfig.java
 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/nifi/NiFiClientConfig.java
index 3a1f42e65d..4254ad0884 100644
--- 
a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/nifi/NiFiClientConfig.java
+++ 
b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/nifi/NiFiClientConfig.java
@@ -16,19 +16,16 @@
  */
 package org.apache.nifi.toolkit.cli.impl.client.nifi;
 
-import java.io.File;
-import java.io.FileInputStream;
+import java.io.IOException;
 import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.security.KeyStore;
-import java.security.SecureRandom;
 import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.KeyManagerFactory;
 import javax.net.ssl.SSLContext;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-import org.apache.nifi.registry.security.util.KeyStoreUtils;
 import org.apache.nifi.registry.security.util.KeystoreType;
+import org.apache.nifi.security.ssl.StandardKeyStoreBuilder;
+import org.apache.nifi.security.ssl.StandardSslContextBuilder;
 import org.apache.nifi.security.util.TlsConfiguration;
 
 /**
@@ -36,8 +33,6 @@ import org.apache.nifi.security.util.TlsConfiguration;
  */
 public class NiFiClientConfig {
 
-    public static final String DEFAULT_PROTOCOL = 
TlsConfiguration.getHighestCurrentSupportedTlsProtocolVersion();
-
     private final String baseUrl;
     private final SSLContext sslContext;
     private final String keystoreFilename;
@@ -63,7 +58,7 @@ public class NiFiClientConfig {
         this.truststoreFilename = builder.truststoreFilename;
         this.truststorePass = builder.truststorePass;
         this.truststoreType = builder.truststoreType;
-        this.protocol = builder.protocol == null ? DEFAULT_PROTOCOL : 
builder.protocol;
+        this.protocol = builder.protocol == null ? 
TlsConfiguration.TLS_PROTOCOL : builder.protocol;
         this.hostnameVerifier = builder.hostnameVerifier;
         this.readTimeout = builder.readTimeout;
         this.connectTimeout = builder.connectTimeout;
@@ -78,58 +73,49 @@ public class NiFiClientConfig {
             return sslContext;
         }
 
-        final KeyManagerFactory keyManagerFactory;
+        final KeyStore keyStore;
         if (keystoreFilename != null && keystorePass != null && keystoreType 
!= null) {
-            try {
-                // prepare the keystore
-                final KeyStore keyStore = 
KeyStoreUtils.getKeyStore(keystoreType.name());
-                try (final InputStream keyStoreStream = new 
FileInputStream(new File(keystoreFilename))) {
-                    keyStore.load(keyStoreStream, keystorePass.toCharArray());
-                }
-                keyManagerFactory = 
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
-
-                if (keyPass == null) {
-                    keyManagerFactory.init(keyStore, 
keystorePass.toCharArray());
-                } else {
-                    keyManagerFactory.init(keyStore, keyPass.toCharArray());
-                }
-            } catch (final Exception e) {
-                throw new IllegalStateException("Failed to load Keystore", e);
+            try (final InputStream keyStoreStream = 
Files.newInputStream(Paths.get(keystoreFilename))) {
+                keyStore = new StandardKeyStoreBuilder()
+                        .inputStream(keyStoreStream)
+                        .password(keystorePass.toCharArray())
+                        .type(keystoreType.name())
+                        .build();
+            } catch (final IOException e) {
+                throw new IllegalStateException(String.format("Read Key Store 
[%s] failed", keystoreFilename), e);
             }
         } else {
-            keyManagerFactory = null;
+            keyStore = null;
         }
 
-        final TrustManagerFactory trustManagerFactory;
+        final KeyStore trustStore;
         if (truststoreFilename != null && truststorePass != null && 
truststoreType != null) {
-            try {
-                // prepare the truststore
-                final KeyStore trustStore = 
KeyStoreUtils.getKeyStore(truststoreType.name());
-                try (final InputStream trustStoreStream = new 
FileInputStream(new File(truststoreFilename))) {
-                    trustStore.load(trustStoreStream, 
truststorePass.toCharArray());
-                }
-                trustManagerFactory = 
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
-                trustManagerFactory.init(trustStore);
-            } catch (final Exception e) {
-                throw new IllegalStateException("Failed to load Truststore", 
e);
+            try (final InputStream keyStoreStream = 
Files.newInputStream(Paths.get(truststoreFilename))) {
+                trustStore = new StandardKeyStoreBuilder()
+                        .inputStream(keyStoreStream)
+                        .password(truststorePass.toCharArray())
+                        .type(truststoreType.name())
+                        .build();
+            } catch (final IOException e) {
+                throw new IllegalStateException(String.format("Read Trust 
Store [%s] failed", truststoreFilename), e);
             }
         } else {
-            trustManagerFactory = null;
+            trustStore = null;
         }
 
-        if (keyManagerFactory != null || trustManagerFactory != null) {
-            try {
-                // initialize the ssl context
-                KeyManager[] keyManagers = keyManagerFactory != null ? 
keyManagerFactory.getKeyManagers() : null;
-                TrustManager[] trustManagers = trustManagerFactory != null ? 
trustManagerFactory.getTrustManagers() : null;
-                final SSLContext sslContext = 
SSLContext.getInstance(getProtocol());
-                sslContext.init(keyManagers, trustManagers, new 
SecureRandom());
-                sslContext.getDefaultSSLParameters().setNeedClientAuth(true);
-
-                return sslContext;
-            } catch (final Exception e) {
-                throw new IllegalStateException("Created keystore and 
truststore but failed to initialize SSLContext", e);
+        if (keyStore != null || trustStore != null) {
+            final StandardSslContextBuilder builder = new 
StandardSslContextBuilder();
+            builder.protocol(protocol);
+
+            if (keyStore != null) {
+                final char[] keyPassword = keyPass == null ? 
keystorePass.toCharArray() : keyPass.toCharArray();
+                builder.keyPassword(keyPassword);
+                builder.keyStore(keyStore);
+            }
+            if (trustStore != null) {
+                builder.trustStore(trustStore);
             }
+            return builder.build();
         } else {
             return null;
         }

Reply via email to