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

JackieTien97 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/master by this push:
     new 4c2fd638a15 Add generic SSL/TLS configuration support (#17854)
4c2fd638a15 is described below

commit 4c2fd638a154ced095c503f6030e547e581cf4a9
Author: Haonan <[email protected]>
AuthorDate: Mon Jun 22 09:28:41 2026 +0800

    Add generic SSL/TLS configuration support (#17854)
---
 external-service-impl/rest/pom.xml                 |  12 -
 .../java/org/apache/iotdb/rest/RestService.java    |   9 +
 .../iotdb/it/env/cluster/config/MppBaseConfig.java |   4 +
 .../it/env/cluster/config/MppCommonConfig.java     |  12 +
 .../env/cluster/config/MppSharedCommonConfig.java  |  14 ++
 .../iotdb/it/env/cluster/env/AbstractEnv.java      | 210 +++++++++++++-----
 .../it/env/remote/config/RemoteCommonConfig.java   |  10 +
 .../org/apache/iotdb/itbase/env/CommonConfig.java  |   4 +
 .../apache/iotdb/session/it/IoTDBClientSSLIT.java  | 233 ++++++++++++++++++++
 integration-test/src/test/resources/test-keystore  | Bin 2710 -> 2742 bytes
 .../src/test/resources/test-truststore             | Bin 1238 -> 1270 bytes
 .../java/org/apache/iotdb/cli/AbstractCli.java     |  14 ++
 .../src/main/java/org/apache/iotdb/cli/Cli.java    |   4 +
 .../org/apache/iotdb/tool/common/Constants.java    |   4 +
 .../org/apache/iotdb/tool/common/OptionsUtil.java  |  10 +
 .../apache/iotdb/tool/data/AbstractDataTool.java   |  37 ++++
 .../apache/iotdb/tool/data/ExportDataTable.java    |   3 +-
 .../org/apache/iotdb/tool/data/ExportDataTree.java |   3 +-
 .../apache/iotdb/tool/data/ImportDataTable.java    |   3 +-
 .../org/apache/iotdb/tool/data/ImportDataTree.java |   3 +-
 .../iotdb/tool/schema/AbstractSchemaTool.java      |  28 +++
 .../iotdb/tool/schema/ExportSchemaTable.java       |   3 +-
 .../apache/iotdb/tool/schema/ExportSchemaTree.java |   3 +-
 .../iotdb/tool/schema/ImportSchemaTable.java       |   3 +-
 .../apache/iotdb/tool/schema/ImportSchemaTree.java |   3 +-
 .../org/apache/iotdb/isession/SessionConfig.java   |   2 +
 .../main/java/org/apache/iotdb/jdbc/Config.java    |   4 +
 .../org/apache/iotdb/jdbc/IoTDBConnection.java     |   5 +-
 .../apache/iotdb/jdbc/IoTDBConnectionParams.java   |   9 +
 .../src/main/java/org/apache/iotdb/jdbc/Utils.java |   6 +
 .../test/java/org/apache/iotdb/jdbc/UtilsTest.java |  11 +
 .../apache/iotdb/rpc/BaseRpcTransportFactory.java  |  29 ++-
 .../java/org/apache/iotdb/rpc/RpcSslUtils.java     | 245 +++++++++++++++++++++
 .../java/org/apache/iotdb/rpc/RpcUtilsTest.java    |   7 +
 .../iotdb/session/AbstractSessionBuilder.java      |   1 +
 .../org/apache/iotdb/session/NodesSupplier.java    |   6 +
 .../java/org/apache/iotdb/session/Session.java     |   8 +
 .../apache/iotdb/session/SessionConnection.java    |  29 ++-
 .../apache/iotdb/session/TableSessionBuilder.java  |  12 +
 .../org/apache/iotdb/session/ThriftConnection.java |   6 +-
 .../org/apache/iotdb/session/pool/SessionPool.java |  13 ++
 .../session/pool/TableSessionPoolBuilder.java      |  12 +
 .../iot/client/SyncIoTConsensusServiceClient.java  |   3 +-
 .../utils/NoHostnameVerificationTrustManager.java  |  88 --------
 .../apache/iotdb/consensus/ratis/utils/Utils.java  |  35 +--
 .../iotdb/db/conf/rest/IoTDBRestServiceConfig.java |  11 +
 .../db/conf/rest/IoTDBRestServiceDescriptor.java   |   4 +
 .../iotdb/db/protocol/client/ConfigNodeClient.java |   3 +-
 .../iotdb/db/protocol/client/an/AINodeClient.java  |   3 +-
 .../conf/iotdb-system.properties.template          |   8 +
 .../commons/client/sync/SyncAINodeClient.java      |   3 +-
 .../client/sync/SyncConfigNodeIServiceClient.java  |   3 +-
 .../sync/SyncDataNodeInternalServiceClient.java    |   3 +-
 .../SyncDataNodeMPPDataExchangeServiceClient.java  |   3 +-
 .../sync/SyncIoTConsensusV2ServiceClient.java      |   3 +-
 .../apache/iotdb/commons/conf/CommonConfig.java    |  11 +
 .../iotdb/commons/conf/CommonDescriptor.java       |   9 +
 .../service/AbstractThriftServiceThread.java       |  52 +----
 pom.xml                                            |  12 +-
 59 files changed, 1011 insertions(+), 277 deletions(-)

diff --git a/external-service-impl/rest/pom.xml 
b/external-service-impl/rest/pom.xml
index fbc02b6dfb8..5287a25440c 100644
--- a/external-service-impl/rest/pom.xml
+++ b/external-service-impl/rest/pom.xml
@@ -38,13 +38,6 @@
             <groupId>org.glassfish.jersey.inject</groupId>
             <artifactId>jersey-hk2</artifactId>
             <scope>runtime</scope>
-            <exclusions>
-                <!-- repeated in node commons -->
-                <exclusion>
-                    <groupId>jakarta.annotation</groupId>
-                    <artifactId>jakarta.annotation-api</artifactId>
-                </exclusion>
-            </exclusions>
         </dependency>
         <dependency>
             <groupId>org.apache.iotdb</groupId>
@@ -87,11 +80,6 @@
                     <groupId>jakarta.validation</groupId>
                     <artifactId>jakarta.validation-api</artifactId>
                 </exclusion>
-                <!-- repeated in node commons -->
-                <exclusion>
-                    <groupId>jakarta.annotation</groupId>
-                    <artifactId>jakarta.annotation-api</artifactId>
-                </exclusion>
             </exclusions>
         </dependency>
         <dependency>
diff --git 
a/external-service-impl/rest/src/main/java/org/apache/iotdb/rest/RestService.java
 
b/external-service-impl/rest/src/main/java/org/apache/iotdb/rest/RestService.java
index acba4e30390..506facdb4ce 100644
--- 
a/external-service-impl/rest/src/main/java/org/apache/iotdb/rest/RestService.java
+++ 
b/external-service-impl/rest/src/main/java/org/apache/iotdb/rest/RestService.java
@@ -21,6 +21,7 @@ import 
org.apache.iotdb.db.conf.rest.IoTDBRestServiceDescriptor;
 import org.apache.iotdb.externalservice.api.IExternalService;
 import org.apache.iotdb.rest.i18n.RestMessages;
 import org.apache.iotdb.rest.protocol.filter.ApiOriginFilter;
+import org.apache.iotdb.rpc.RpcSslUtils;
 
 import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
 import org.eclipse.jetty.ee10.servlet.ServletHolder;
@@ -52,6 +53,7 @@ public class RestService implements IExternalService {
       String trustStorePath,
       String keyStorePwd,
       String trustStorePwd,
+      String sslProtocol,
       int idleTime,
       boolean clientAuth) {
     server = new Server();
@@ -61,6 +63,7 @@ public class RestService implements IExternalService {
     httpsConfig.addCustomizer(new SecureRequestCustomizer());
 
     SslContextFactory.Server sslContextFactory = new 
SslContextFactory.Server();
+    configureSSL(sslContextFactory, sslProtocol);
     sslContextFactory.setKeyStorePath(keyStorePath);
     sslContextFactory.setKeyStorePassword(keyStorePwd);
     if (clientAuth) {
@@ -125,6 +128,7 @@ public class RestService implements IExternalService {
           config.getTrustStorePath(),
           config.getKeyStorePwd(),
           config.getTrustStorePwd(),
+          config.getSslProtocol(),
           config.getIdleTimeoutInSeconds(),
           config.isClientAuth());
     } else {
@@ -142,4 +146,9 @@ public class RestService implements IExternalService {
       server.destroy();
     }
   }
+
+  private void configureSSL(SslContextFactory.Server sslContextFactory, String 
sslProtocol) {
+    String protocol = RpcSslUtils.normalizeProtocol(sslProtocol);
+    sslContextFactory.setProtocol(protocol);
+  }
 }
diff --git 
a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppBaseConfig.java
 
b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppBaseConfig.java
index e0758de70c9..69b2e540e96 100644
--- 
a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppBaseConfig.java
+++ 
b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppBaseConfig.java
@@ -120,6 +120,10 @@ public abstract class MppBaseConfig {
     }
   }
 
+  public final String getProperty(@NotNull String key, String defaultValue) {
+    return properties.getProperty(key, defaultValue);
+  }
+
   /** Create an instance but with empty properties. */
   public abstract MppBaseConfig emptyClone();
 }
diff --git 
a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppCommonConfig.java
 
b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppCommonConfig.java
index d2743e89a8a..4dd7f857162 100644
--- 
a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppCommonConfig.java
+++ 
b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppCommonConfig.java
@@ -626,6 +626,12 @@ public class MppCommonConfig extends MppBaseConfig 
implements CommonConfig {
     return this;
   }
 
+  @Override
+  public CommonConfig setEnableThriftClientSSL(boolean enableThriftClientSSL) {
+    setProperty("enable_thrift_ssl", String.valueOf(enableThriftClientSSL));
+    return this;
+  }
+
   @Override
   public CommonConfig setEnableInternalSSL(boolean enableInternalSSL) {
     setProperty("enable_internal_ssl", String.valueOf(enableInternalSSL));
@@ -656,6 +662,12 @@ public class MppCommonConfig extends MppBaseConfig 
implements CommonConfig {
     return this;
   }
 
+  @Override
+  public CommonConfig setSslProtocol(String sslProtocol) {
+    setProperty("ssl_protocol", sslProtocol);
+    return this;
+  }
+
   @Override
   public CommonConfig setDatanodeMemoryProportion(String 
datanodeMemoryProportion) {
     setProperty("datanode_memory_proportion", datanodeMemoryProportion);
diff --git 
a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppSharedCommonConfig.java
 
b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppSharedCommonConfig.java
index 708e7466ab1..8e0398de309 100644
--- 
a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppSharedCommonConfig.java
+++ 
b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppSharedCommonConfig.java
@@ -651,6 +651,13 @@ public class MppSharedCommonConfig implements CommonConfig 
{
     return this;
   }
 
+  @Override
+  public CommonConfig setEnableThriftClientSSL(boolean enableThriftClientSSL) {
+    cnConfig.setEnableThriftClientSSL(enableThriftClientSSL);
+    dnConfig.setEnableThriftClientSSL(enableThriftClientSSL);
+    return this;
+  }
+
   @Override
   public CommonConfig setEnableInternalSSL(boolean enableInternalSSL) {
     cnConfig.setEnableInternalSSL(enableInternalSSL);
@@ -686,6 +693,13 @@ public class MppSharedCommonConfig implements CommonConfig 
{
     return this;
   }
 
+  @Override
+  public CommonConfig setSslProtocol(String sslProtocol) {
+    cnConfig.setSslProtocol(sslProtocol);
+    dnConfig.setSslProtocol(sslProtocol);
+    return this;
+  }
+
   @Override
   public CommonConfig setDatanodeMemoryProportion(String 
datanodeMemoryProportion) {
     dnConfig.setDatanodeMemoryProportion(datanodeMemoryProportion);
diff --git 
a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/env/AbstractEnv.java
 
b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/env/AbstractEnv.java
index df0b31090f5..342b4aba26d 100644
--- 
a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/env/AbstractEnv.java
+++ 
b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/env/AbstractEnv.java
@@ -688,6 +688,83 @@ public abstract class AbstractEnv implements BaseEnv {
     clusterConfig = new MppClusterConfig();
   }
 
+  private boolean isThriftClientSSLEnabled() {
+    return 
Boolean.parseBoolean(getDataNodeCommonConfigProperty("enable_thrift_ssl", 
"false"));
+  }
+
+  private String getDataNodeCommonConfigProperty(final String key, final 
String defaultValue) {
+    return ((MppCommonConfig) clusterConfig.getDataNodeCommonConfig())
+        .getProperty(key, defaultValue);
+  }
+
+  private String getClientSSLProtocol() {
+    return getDataNodeCommonConfigProperty("ssl_protocol", 
SessionConfig.DEFAULT_SSL_PROTOCOL);
+  }
+
+  private Properties constructConnectionProperties(
+      final String username, final String password, final String sqlDialect) {
+    final Properties info = BaseEnv.constructProperties(username, password, 
sqlDialect);
+    if (isThriftClientSSLEnabled()) {
+      info.put(Config.USE_SSL, Boolean.TRUE.toString());
+      putIfPresent(
+          info, Config.TRUST_STORE, 
getDataNodeCommonConfigProperty("trust_store_path", ""));
+      putIfPresent(
+          info, Config.TRUST_STORE_PWD, 
getDataNodeCommonConfigProperty("trust_store_pwd", ""));
+      putIfPresent(info, Config.SSL_PROTOCOL, getClientSSLProtocol());
+    }
+    return info;
+  }
+
+  private void putIfPresent(final Properties properties, final String key, 
final String value) {
+    if (value != null && !value.isEmpty()) {
+      properties.put(key, value);
+    }
+  }
+
+  private Session.Builder configureClientSSL(final Session.Builder builder) {
+    if (isThriftClientSSLEnabled()) {
+      builder
+          .useSSL(true)
+          .trustStore(getDataNodeCommonConfigProperty("trust_store_path", ""))
+          .trustStorePwd(getDataNodeCommonConfigProperty("trust_store_pwd", 
""))
+          .sslProtocol(getClientSSLProtocol());
+    }
+    return builder;
+  }
+
+  private TableSessionBuilder configureClientSSL(final TableSessionBuilder 
builder) {
+    if (isThriftClientSSLEnabled()) {
+      builder
+          .useSSL(true)
+          .trustStore(getDataNodeCommonConfigProperty("trust_store_path", ""))
+          .trustStorePwd(getDataNodeCommonConfigProperty("trust_store_pwd", 
""))
+          .sslProtocol(getClientSSLProtocol());
+    }
+    return builder;
+  }
+
+  private SessionPool.Builder configureClientSSL(final SessionPool.Builder 
builder) {
+    if (isThriftClientSSLEnabled()) {
+      builder
+          .useSSL(true)
+          .trustStore(getDataNodeCommonConfigProperty("trust_store_path", ""))
+          .trustStorePwd(getDataNodeCommonConfigProperty("trust_store_pwd", 
""))
+          .sslProtocol(getClientSSLProtocol());
+    }
+    return builder;
+  }
+
+  private TableSessionPoolBuilder configureClientSSL(final 
TableSessionPoolBuilder builder) {
+    if (isThriftClientSSLEnabled()) {
+      builder
+          .useSSL(true)
+          .trustStore(getDataNodeCommonConfigProperty("trust_store_path", ""))
+          .trustStorePwd(getDataNodeCommonConfigProperty("trust_store_pwd", 
""))
+          .sslProtocol(getClientSSLProtocol());
+    }
+    return builder;
+  }
+
   @Override
   public Connection getConnection(
       final String username, final String password, final String sqlDialect) 
throws SQLException {
@@ -769,7 +846,8 @@ public abstract class AbstractEnv implements BaseEnv {
     final DataNodeWrapper dataNode =
         
this.dataNodeWrapperList.get(rand.nextInt(this.dataNodeWrapperList.size()));
     final Session session =
-        new 
Session.Builder().host(dataNode.getIp()).port(dataNode.getPort()).build();
+        configureClientSSL(new 
Session.Builder().host(dataNode.getIp()).port(dataNode.getPort()))
+            .build();
     session.open();
     return session;
   }
@@ -779,10 +857,11 @@ public abstract class AbstractEnv implements BaseEnv {
     final DataNodeWrapper dataNode =
         
this.dataNodeWrapperList.get(rand.nextInt(this.dataNodeWrapperList.size()));
     final Session session =
-        new Session.Builder()
-            .host(dataNode.getIp())
-            .port(dataNode.getPort())
-            .zoneId(zoneId)
+        configureClientSSL(
+                new Session.Builder()
+                    .host(dataNode.getIp())
+                    .port(dataNode.getPort())
+                    .zoneId(zoneId))
             .build();
     session.open();
     return session;
@@ -794,11 +873,12 @@ public abstract class AbstractEnv implements BaseEnv {
     final DataNodeWrapper dataNode =
         
this.dataNodeWrapperList.get(rand.nextInt(this.dataNodeWrapperList.size()));
     final Session session =
-        new Session.Builder()
-            .host(dataNode.getIp())
-            .port(dataNode.getPort())
-            .username(userName)
-            .password(password)
+        configureClientSSL(
+                new Session.Builder()
+                    .host(dataNode.getIp())
+                    .port(dataNode.getPort())
+                    .username(userName)
+                    .password(password))
             .build();
     session.open();
     return session;
@@ -808,16 +888,17 @@ public abstract class AbstractEnv implements BaseEnv {
   public ISession getSessionConnection(final List<String> nodeUrls)
       throws IoTDBConnectionException {
     final Session session =
-        new Session.Builder()
-            .nodeUrls(nodeUrls)
-            .username(SessionConfig.DEFAULT_USER)
-            .password(SessionConfig.DEFAULT_PASSWORD)
-            .fetchSize(SessionConfig.DEFAULT_FETCH_SIZE)
-            .zoneId(null)
-            
.thriftDefaultBufferSize(SessionConfig.DEFAULT_INITIAL_BUFFER_CAPACITY)
-            .thriftMaxFrameSize(SessionConfig.DEFAULT_MAX_FRAME_SIZE)
-            .enableRedirection(SessionConfig.DEFAULT_REDIRECTION_MODE)
-            .version(SessionConfig.DEFAULT_VERSION)
+        configureClientSSL(
+                new Session.Builder()
+                    .nodeUrls(nodeUrls)
+                    .username(SessionConfig.DEFAULT_USER)
+                    .password(SessionConfig.DEFAULT_PASSWORD)
+                    .fetchSize(SessionConfig.DEFAULT_FETCH_SIZE)
+                    .zoneId(null)
+                    
.thriftDefaultBufferSize(SessionConfig.DEFAULT_INITIAL_BUFFER_CAPACITY)
+                    .thriftMaxFrameSize(SessionConfig.DEFAULT_MAX_FRAME_SIZE)
+                    .enableRedirection(SessionConfig.DEFAULT_REDIRECTION_MODE)
+                    .version(SessionConfig.DEFAULT_VERSION))
             .build();
     session.open();
     return session;
@@ -827,8 +908,9 @@ public abstract class AbstractEnv implements BaseEnv {
   public ITableSession getTableSessionConnection() throws 
IoTDBConnectionException {
     final DataNodeWrapper dataNode =
         
this.dataNodeWrapperList.get(rand.nextInt(this.dataNodeWrapperList.size()));
-    return new TableSessionBuilder()
-        .nodeUrls(Collections.singletonList(dataNode.getIpAndPortString()))
+    return configureClientSSL(
+            new TableSessionBuilder()
+                
.nodeUrls(Collections.singletonList(dataNode.getIpAndPortString())))
         .build();
   }
 
@@ -837,10 +919,11 @@ public abstract class AbstractEnv implements BaseEnv {
       throws IoTDBConnectionException {
     final DataNodeWrapper dataNode =
         
this.dataNodeWrapperList.get(rand.nextInt(this.dataNodeWrapperList.size()));
-    return new TableSessionBuilder()
-        .nodeUrls(Collections.singletonList(dataNode.getIpAndPortString()))
-        .username(userName)
-        .password(password)
+    return configureClientSSL(
+            new TableSessionBuilder()
+                
.nodeUrls(Collections.singletonList(dataNode.getIpAndPortString()))
+                .username(userName)
+                .password(password))
         .build();
   }
 
@@ -849,23 +932,25 @@ public abstract class AbstractEnv implements BaseEnv {
       throws IoTDBConnectionException {
     final DataNodeWrapper dataNode =
         
this.dataNodeWrapperList.get(rand.nextInt(this.dataNodeWrapperList.size()));
-    return new TableSessionBuilder()
-        .nodeUrls(Collections.singletonList(dataNode.getIpAndPortString()))
-        .database(database)
+    return configureClientSSL(
+            new TableSessionBuilder()
+                
.nodeUrls(Collections.singletonList(dataNode.getIpAndPortString()))
+                .database(database))
         .build();
   }
 
   public ITableSession getTableSessionConnection(List<String> nodeUrls)
       throws IoTDBConnectionException {
-    return new TableSessionBuilder()
-        .nodeUrls(nodeUrls)
-        .username(SessionConfig.DEFAULT_USER)
-        .password(SessionConfig.DEFAULT_PASSWORD)
-        .fetchSize(SessionConfig.DEFAULT_FETCH_SIZE)
-        .zoneId(null)
-        .thriftDefaultBufferSize(SessionConfig.DEFAULT_INITIAL_BUFFER_CAPACITY)
-        .thriftMaxFrameSize(SessionConfig.DEFAULT_MAX_FRAME_SIZE)
-        .enableRedirection(SessionConfig.DEFAULT_REDIRECTION_MODE)
+    return configureClientSSL(
+            new TableSessionBuilder()
+                .nodeUrls(nodeUrls)
+                .username(SessionConfig.DEFAULT_USER)
+                .password(SessionConfig.DEFAULT_PASSWORD)
+                .fetchSize(SessionConfig.DEFAULT_FETCH_SIZE)
+                .zoneId(null)
+                
.thriftDefaultBufferSize(SessionConfig.DEFAULT_INITIAL_BUFFER_CAPACITY)
+                .thriftMaxFrameSize(SessionConfig.DEFAULT_MAX_FRAME_SIZE)
+                .enableRedirection(SessionConfig.DEFAULT_REDIRECTION_MODE))
         .build();
   }
 
@@ -873,12 +958,13 @@ public abstract class AbstractEnv implements BaseEnv {
   public ISessionPool getSessionPool(final int maxSize) {
     final DataNodeWrapper dataNode =
         
this.dataNodeWrapperList.get(rand.nextInt(this.dataNodeWrapperList.size()));
-    return new SessionPool.Builder()
-        .host(dataNode.getIp())
-        .port(dataNode.getPort())
-        .user(SessionConfig.DEFAULT_USER)
-        .password(SessionConfig.DEFAULT_PASSWORD)
-        .maxSize(maxSize)
+    return configureClientSSL(
+            new SessionPool.Builder()
+                .host(dataNode.getIp())
+                .port(dataNode.getPort())
+                .user(SessionConfig.DEFAULT_USER)
+                .password(SessionConfig.DEFAULT_PASSWORD)
+                .maxSize(maxSize))
         .build();
   }
 
@@ -886,11 +972,12 @@ public abstract class AbstractEnv implements BaseEnv {
   public ITableSessionPool getTableSessionPool(final int maxSize) {
     final DataNodeWrapper dataNode =
         
this.dataNodeWrapperList.get(rand.nextInt(this.dataNodeWrapperList.size()));
-    return new TableSessionPoolBuilder()
-        .nodeUrls(Collections.singletonList(dataNode.getIpAndPortString()))
-        .user(SessionConfig.DEFAULT_USER)
-        .password(SessionConfig.DEFAULT_PASSWORD)
-        .maxSize(maxSize)
+    return configureClientSSL(
+            new TableSessionPoolBuilder()
+                
.nodeUrls(Collections.singletonList(dataNode.getIpAndPortString()))
+                .user(SessionConfig.DEFAULT_USER)
+                .password(SessionConfig.DEFAULT_PASSWORD)
+                .maxSize(maxSize))
         .build();
   }
 
@@ -898,12 +985,13 @@ public abstract class AbstractEnv implements BaseEnv {
   public ITableSessionPool getTableSessionPool(final int maxSize, final String 
database) {
     DataNodeWrapper dataNode =
         
this.dataNodeWrapperList.get(rand.nextInt(this.dataNodeWrapperList.size()));
-    return new TableSessionPoolBuilder()
-        .nodeUrls(Collections.singletonList(dataNode.getIpAndPortString()))
-        .user(SessionConfig.DEFAULT_USER)
-        .password(SessionConfig.DEFAULT_PASSWORD)
-        .database(database)
-        .maxSize(maxSize)
+    return configureClientSSL(
+            new TableSessionPoolBuilder()
+                
.nodeUrls(Collections.singletonList(dataNode.getIpAndPortString()))
+                .user(SessionConfig.DEFAULT_USER)
+                .password(SessionConfig.DEFAULT_PASSWORD)
+                .database(database)
+                .maxSize(maxSize))
         .build();
   }
 
@@ -927,7 +1015,7 @@ public abstract class AbstractEnv implements BaseEnv {
             Config.IOTDB_URL_PREFIX
                 + endpoint
                 + getParam(version, NODE_NETWORK_TIMEOUT_MS, ZERO_TIME_ZONE),
-            BaseEnv.constructProperties(username, password, sqlDialect));
+            constructConnectionProperties(username, password, sqlDialect));
     return new NodeConnection(
         endpoint,
         NodeConnection.NodeRole.DATA_NODE,
@@ -984,7 +1072,7 @@ public abstract class AbstractEnv implements BaseEnv {
                               Config.IOTDB_URL_PREFIX
                                   + endpoint
                                   + getParam(version, NODE_NETWORK_TIMEOUT_MS, 
ZERO_TIME_ZONE),
-                              BaseEnv.constructProperties(username, password, 
sqlDialect))));
+                              constructConnectionProperties(username, 
password, sqlDialect))));
             });
     return readConnRequestDelegate.requestAll();
   }
@@ -1031,7 +1119,7 @@ public abstract class AbstractEnv implements BaseEnv {
                     Config.IOTDB_URL_PREFIX
                         + dataNode.getIpAndPortString()
                         + getParam(version, NODE_NETWORK_TIMEOUT_MS, 
ZERO_TIME_ZONE),
-                    BaseEnv.constructProperties(username, password, 
sqlDialect))));
+                    constructConnectionProperties(username, password, 
sqlDialect))));
 
     return readConnRequestDelegate.requestAll();
   }
@@ -1063,8 +1151,10 @@ public abstract class AbstractEnv implements BaseEnv {
                           Config.IOTDB_URL_PREFIX
                               + dataNodeEndpoint
                               + getParam(null, NODE_NETWORK_TIMEOUT_MS, 
ZERO_TIME_ZONE),
-                          System.getProperty("User", "root"),
-                          System.getProperty("Password", "root"))) {
+                          constructConnectionProperties(
+                              System.getProperty("User", "root"),
+                              System.getProperty("Password", "root"),
+                              TREE_SQL_DIALECT))) {
                 logger.info("Successfully connecting to DataNode: {}.", 
dataNodeEndpoint);
                 return null;
               } catch (final Exception e) {
diff --git 
a/integration-test/src/main/java/org/apache/iotdb/it/env/remote/config/RemoteCommonConfig.java
 
b/integration-test/src/main/java/org/apache/iotdb/it/env/remote/config/RemoteCommonConfig.java
index 7d9499773f0..a2d10c01009 100644
--- 
a/integration-test/src/main/java/org/apache/iotdb/it/env/remote/config/RemoteCommonConfig.java
+++ 
b/integration-test/src/main/java/org/apache/iotdb/it/env/remote/config/RemoteCommonConfig.java
@@ -442,6 +442,11 @@ public class RemoteCommonConfig implements CommonConfig {
     return this;
   }
 
+  @Override
+  public CommonConfig setEnableThriftClientSSL(boolean enableThriftClientSSL) {
+    return this;
+  }
+
   @Override
   public CommonConfig setSubscriptionPrefetchTsFileBatchMaxDelayInMs(
       int subscriptionPrefetchTsFileBatchMaxDelayInMs) {
@@ -479,6 +484,11 @@ public class RemoteCommonConfig implements CommonConfig {
     return this;
   }
 
+  @Override
+  public CommonConfig setSslProtocol(String sslProtocol) {
+    return this;
+  }
+
   @Override
   public CommonConfig setDatanodeMemoryProportion(String 
datanodeMemoryProportion) {
     return this;
diff --git 
a/integration-test/src/main/java/org/apache/iotdb/itbase/env/CommonConfig.java 
b/integration-test/src/main/java/org/apache/iotdb/itbase/env/CommonConfig.java
index 9e446e97d34..5b51a6a8cf9 100644
--- 
a/integration-test/src/main/java/org/apache/iotdb/itbase/env/CommonConfig.java
+++ 
b/integration-test/src/main/java/org/apache/iotdb/itbase/env/CommonConfig.java
@@ -201,6 +201,8 @@ public interface CommonConfig {
 
   CommonConfig setEnforceStrongPassword(boolean enforceStrongPassword);
 
+  CommonConfig setEnableThriftClientSSL(boolean enableThriftClientSSL);
+
   CommonConfig setEnableInternalSSL(boolean enableInternalSSL);
 
   CommonConfig setKeyStorePath(String keyStorePath);
@@ -211,6 +213,8 @@ public interface CommonConfig {
 
   CommonConfig setTrustStorePwd(String trustStorePwd);
 
+  CommonConfig setSslProtocol(String sslProtocol);
+
   CommonConfig setDatanodeMemoryProportion(String datanodeMemoryProportion);
 
   CommonConfig setEnableAuditLog(boolean enableAuditLog);
diff --git 
a/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBClientSSLIT.java
 
b/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBClientSSLIT.java
new file mode 100644
index 00000000000..23906fdb4c8
--- /dev/null
+++ 
b/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBClientSSLIT.java
@@ -0,0 +1,233 @@
+/*
+ * 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.iotdb.session.it;
+
+import org.apache.iotdb.isession.ISession;
+import org.apache.iotdb.isession.ITableSession;
+import org.apache.iotdb.isession.SessionConfig;
+import org.apache.iotdb.isession.SessionDataSet;
+import org.apache.iotdb.it.env.EnvFactory;
+import org.apache.iotdb.it.env.cluster.node.DataNodeWrapper;
+import org.apache.iotdb.it.framework.IoTDBTestRunner;
+import org.apache.iotdb.itbase.category.ClusterIT;
+import org.apache.iotdb.itbase.category.LocalStandaloneIT;
+import org.apache.iotdb.itbase.category.TableClusterIT;
+import org.apache.iotdb.itbase.category.TableLocalStandaloneIT;
+import org.apache.iotdb.jdbc.Config;
+import org.apache.iotdb.rpc.IoTDBConnectionException;
+import org.apache.iotdb.session.Session;
+import org.apache.iotdb.session.TableSessionBuilder;
+
+import org.apache.tsfile.read.common.RowRecord;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.util.Collections;
+import java.util.Properties;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+
+@RunWith(IoTDBTestRunner.class)
+@Category({
+  LocalStandaloneIT.class,
+  ClusterIT.class,
+  TableLocalStandaloneIT.class,
+  TableClusterIT.class
+})
+public class IoTDBClientSSLIT {
+
+  private static final String STORE_PASSWORD = "thrift";
+  private static String keyDir;
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    keyDir =
+        System.getProperty("user.dir")
+            + File.separator
+            + "target"
+            + File.separator
+            + "test-classes"
+            + File.separator;
+
+    EnvFactory.getEnv()
+        .getConfig()
+        .getCommonConfig()
+        .setEnableThriftClientSSL(true)
+        .setKeyStorePath(keyStorePath())
+        .setKeyStorePwd(STORE_PASSWORD)
+        .setTrustStorePath(trustStorePath())
+        .setTrustStorePwd(STORE_PASSWORD)
+        .setSslProtocol(SessionConfig.DEFAULT_SSL_PROTOCOL);
+    EnvFactory.getEnv().initClusterEnvironment();
+  }
+
+  @After
+  public void tearDown() {
+    try (ISession session = newSSLSession()) {
+      deleteTreeDatabase(session, "root.client_ssl_tree");
+      deleteTreeDatabase(session, "root.client_ssl_jdbc");
+    } catch (Exception ignored) {
+      // ignored
+    }
+    try (ITableSession session = newSSLTableSession()) {
+      session.executeNonQueryStatement("DROP DATABASE IF EXISTS 
client_ssl_table");
+    } catch (Exception ignored) {
+      // ignored
+    }
+  }
+
+  @AfterClass
+  public static void tearDownClass() {
+    EnvFactory.getEnv().cleanClusterEnvironment();
+  }
+
+  @Test
+  public void nonSSLClientCanNotConnectToSSLPort() {
+    final DataNodeWrapper dataNode = EnvFactory.getEnv().getDataNodeWrapper(0);
+    final Session session =
+        new 
Session.Builder().host(dataNode.getIp()).port(dataNode.getPort()).build();
+
+    assertThrows(IoTDBConnectionException.class, session::open);
+  }
+
+  @Test
+  public void treeSessionCanConnectWithSSL() throws Exception {
+    try (ISession session = newSSLSession()) {
+      session.executeNonQueryStatement("CREATE DATABASE root.client_ssl_tree");
+      session.executeNonQueryStatement(
+          "CREATE TIMESERIES root.client_ssl_tree.d1.s1 WITH DATATYPE=INT32, 
ENCODING=PLAIN");
+      session.executeNonQueryStatement(
+          "INSERT INTO root.client_ssl_tree.d1(time, s1) VALUES (1, 11)");
+
+      try (SessionDataSet dataSet =
+          session.executeQueryStatement("SELECT s1 FROM 
root.client_ssl_tree.d1")) {
+        assertTrue(dataSet.hasNext());
+        final RowRecord record = dataSet.next();
+        assertEquals(1L, record.getTimestamp());
+        assertEquals(11, record.getFields().get(0).getIntV());
+        assertFalse(dataSet.hasNext());
+      }
+    }
+  }
+
+  @Test
+  public void tableSessionCanConnectWithSSL() throws Exception {
+    try (ITableSession session = newSSLTableSession()) {
+      session.executeNonQueryStatement("CREATE DATABASE IF NOT EXISTS 
client_ssl_table");
+      session.executeNonQueryStatement("USE client_ssl_table");
+      session.executeNonQueryStatement(
+          "CREATE TABLE IF NOT EXISTS ssl_table (tag1 STRING TAG, value INT32 
FIELD)");
+      session.executeNonQueryStatement(
+          "INSERT INTO ssl_table(time, tag1, value) VALUES (1, 'tag1', 22)");
+
+      try (SessionDataSet dataSet =
+          session.executeQueryStatement("SELECT time, value FROM ssl_table 
WHERE tag1 = 'tag1'")) {
+        assertTrue(dataSet.hasNext());
+        final RowRecord record = dataSet.next();
+        assertEquals(1L, record.getFields().get(0).getLongV());
+        assertEquals(22, record.getFields().get(1).getIntV());
+        assertFalse(dataSet.hasNext());
+      }
+    }
+  }
+
+  @Test
+  public void jdbcCanConnectWithSSL() throws Exception {
+    final DataNodeWrapper dataNode = EnvFactory.getEnv().getDataNodeWrapper(0);
+
+    try (Connection connection =
+            DriverManager.getConnection(
+                Config.IOTDB_URL_PREFIX + dataNode.getIpAndPortString(), 
sslProperties());
+        Statement statement = connection.createStatement()) {
+      statement.execute("CREATE DATABASE root.client_ssl_jdbc");
+      statement.execute(
+          "CREATE TIMESERIES root.client_ssl_jdbc.d1.s1 WITH DATATYPE=INT32, 
ENCODING=PLAIN");
+      statement.execute("INSERT INTO root.client_ssl_jdbc.d1(time, s1) VALUES 
(1, 33)");
+
+      try (ResultSet resultSet = statement.executeQuery("SELECT s1 FROM 
root.client_ssl_jdbc.d1")) {
+        assertTrue(resultSet.next());
+        assertEquals(1L, resultSet.getLong(1));
+        assertEquals(33, resultSet.getInt(2));
+        assertFalse(resultSet.next());
+      }
+    }
+  }
+
+  private static ISession newSSLSession() throws IoTDBConnectionException {
+    final DataNodeWrapper dataNode = EnvFactory.getEnv().getDataNodeWrapper(0);
+    final Session session =
+        new Session.Builder()
+            .host(dataNode.getIp())
+            .port(dataNode.getPort())
+            .useSSL(true)
+            .trustStore(trustStorePath())
+            .trustStorePwd(STORE_PASSWORD)
+            .build();
+    session.open();
+    return session;
+  }
+
+  private static ITableSession newSSLTableSession() throws 
IoTDBConnectionException {
+    final DataNodeWrapper dataNode = EnvFactory.getEnv().getDataNodeWrapper(0);
+    return new TableSessionBuilder()
+        .nodeUrls(Collections.singletonList(dataNode.getIpAndPortString()))
+        .useSSL(true)
+        .trustStore(trustStorePath())
+        .trustStorePwd(STORE_PASSWORD)
+        .build();
+  }
+
+  private static Properties sslProperties() {
+    final Properties properties = new Properties();
+    properties.put("user", SessionConfig.DEFAULT_USER);
+    properties.put("password", SessionConfig.DEFAULT_PASSWORD);
+    properties.put(Config.USE_SSL, Boolean.TRUE.toString());
+    properties.put(Config.TRUST_STORE, trustStorePath());
+    properties.put(Config.TRUST_STORE_PWD, STORE_PASSWORD);
+    return properties;
+  }
+
+  private void deleteTreeDatabase(final ISession session, final String 
database) {
+    try {
+      session.executeNonQueryStatement("DELETE DATABASE " + database);
+    } catch (Exception ignored) {
+      // ignored
+    }
+  }
+
+  private static String keyStorePath() {
+    return keyDir + "test-keystore";
+  }
+
+  private static String trustStorePath() {
+    return keyDir + "test-truststore";
+  }
+}
diff --git a/integration-test/src/test/resources/test-keystore 
b/integration-test/src/test/resources/test-keystore
index 2346c547259..76605794717 100644
Binary files a/integration-test/src/test/resources/test-keystore and 
b/integration-test/src/test/resources/test-keystore differ
diff --git a/integration-test/src/test/resources/test-truststore 
b/integration-test/src/test/resources/test-truststore
index 92c5b819f21..c6b93a476c5 100644
Binary files a/integration-test/src/test/resources/test-truststore and 
b/integration-test/src/test/resources/test-truststore differ
diff --git 
a/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java 
b/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java
index 3d8535aac3c..017f0a1a6ca 100644
--- a/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java
+++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/AbstractCli.java
@@ -77,12 +77,15 @@ public abstract class AbstractCli {
 
   static final String TRUST_STORE_PWD_ARGS = "tpw";
 
+  static final String SSL_PROTOCOL_ARGS = "ssl_protocol";
+
   private static final String EXECUTE_NAME = "execute";
 
   private static final String USE_SSL = "use_ssl";
   private static final String TRUST_STORE = "trust_store";
 
   private static final String TRUST_STORE_PWD = "trust_store_pwd";
+  private static final String SSL_PROTOCOL = "ssl_protocol";
   private static final String NULL = "null";
 
   static final int CODE_OK = 0;
@@ -132,6 +135,7 @@ public abstract class AbstractCli {
   static String trustStore;
   // TODO: Make non-static
   static String trustStorePwd;
+  static String sslProtocol;
 
   static String execute;
   static boolean hasExecuteSQL = false;
@@ -156,6 +160,7 @@ public abstract class AbstractCli {
     keywordSet.add("-" + USE_SSL_ARGS);
     keywordSet.add("-" + TRUST_STORE_ARGS);
     keywordSet.add("-" + TRUST_STORE_PWD_ARGS);
+    keywordSet.add("-" + SSL_PROTOCOL_ARGS);
     keywordSet.add("-" + EXECUTE_ARGS);
     keywordSet.add("-" + ISO8601_ARGS);
     keywordSet.add("-" + RPC_COMPRESS_ARGS);
@@ -214,6 +219,15 @@ public abstract class AbstractCli {
             .build();
     options.addOption(useSSL);
 
+    Option sslProtocol =
+        Option.builder(SSL_PROTOCOL_ARGS)
+            .longOpt(SSL_PROTOCOL)
+            .argName(SSL_PROTOCOL)
+            .hasArg()
+            .desc("SSL protocol. (optional)")
+            .build();
+    options.addOption(sslProtocol);
+
     Option execute =
         Option.builder(EXECUTE_ARGS)
             .argName(EXECUTE_NAME)
diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/Cli.java 
b/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/Cli.java
index d1bbd6165f6..a9e911be6ed 100644
--- a/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/Cli.java
+++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/cli/Cli.java
@@ -111,6 +111,9 @@ public class Cli extends AbstractCli {
       info.setProperty("use_ssl", useSsl);
       info.setProperty("trust_store", trustStore);
       info.setProperty("trust_store_pwd", trustStorePwd);
+      if (sslProtocol != null) {
+        info.setProperty(Config.SSL_PROTOCOL, sslProtocol);
+      }
     }
     info.setProperty("user", username);
     info.setProperty("password", password);
@@ -159,6 +162,7 @@ public class Cli extends AbstractCli {
   private static void serve(CliContext ctx) {
     try {
       useSsl = commandLine.getOptionValue(USE_SSL_ARGS);
+      sslProtocol = commandLine.getOptionValue(SSL_PROTOCOL_ARGS);
       if (Boolean.parseBoolean(useSsl)) {
         trustStore = ctx.getLineReader().readLine("please input your 
trust_store:", '\0');
         trustStorePwd = ctx.getLineReader().readLine("please input your 
trust_store_pwd:", '\0');
diff --git 
a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/common/Constants.java 
b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/common/Constants.java
index 0d4c5f218b7..a1063260957 100644
--- a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/common/Constants.java
+++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/common/Constants.java
@@ -68,6 +68,10 @@ public class Constants {
   public static final String TRUST_STORE_PWD_NAME = "trust_store_password";
   public static final String TRUST_STORE_PWD_DESC = "Trust store password. 
(optional)";
 
+  public static final String SSL_PROTOCOL_ARGS = "ssl_protocol";
+  public static final String SSL_PROTOCOL_NAME = "ssl_protocol";
+  public static final String SSL_PROTOCOL_DESC = "SSL protocol. (optional)";
+
   public static final String FILE_TYPE_ARGS = "ft";
   public static final String FILE_TYPE_NAME = "file_type";
   public static final String FILE_TYPE_ARGS_NAME = "format";
diff --git 
a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/common/OptionsUtil.java 
b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/common/OptionsUtil.java
index b60809eba63..1f79b303f6e 100644
--- 
a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/common/OptionsUtil.java
+++ 
b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/common/OptionsUtil.java
@@ -133,6 +133,16 @@ public class OptionsUtil extends Constants {
             .build();
     options.addOption(opTrustStorePwd);
 
+    Option opSslProtocol =
+        Option.builder(SSL_PROTOCOL_ARGS)
+            .longOpt(SSL_PROTOCOL_NAME)
+            .optionalArg(true)
+            .argName(SSL_PROTOCOL_NAME)
+            .hasArg()
+            .desc(SSL_PROTOCOL_DESC)
+            .build();
+    options.addOption(opSslProtocol);
+
     return options;
   }
 
diff --git 
a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/AbstractDataTool.java
 
b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/AbstractDataTool.java
index 4ef95c78eda..6ea79a5b582 100644
--- 
a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/AbstractDataTool.java
+++ 
b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/AbstractDataTool.java
@@ -34,6 +34,9 @@ import org.apache.iotdb.isession.SessionDataSet;
 import org.apache.iotdb.rpc.IoTDBConnectionException;
 import org.apache.iotdb.rpc.StatementExecutionException;
 import org.apache.iotdb.session.Session;
+import org.apache.iotdb.session.TableSessionBuilder;
+import org.apache.iotdb.session.pool.SessionPool;
+import org.apache.iotdb.session.pool.TableSessionPoolBuilder;
 import org.apache.iotdb.tool.common.Constants;
 import org.apache.iotdb.tool.common.ImportTsFileOperation;
 
@@ -94,6 +97,7 @@ public abstract class AbstractDataTool {
   protected static Boolean useSsl;
   protected static String trustStore;
   protected static String trustStorePwd;
+  protected static String sslProtocol;
   protected static Boolean aligned;
   protected static String database;
   protected static String startTime;
@@ -134,6 +138,38 @@ public abstract class AbstractDataTool {
 
   protected AbstractDataTool() {}
 
+  protected static Session.Builder configureSsl(Session.Builder builder) {
+    builder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd);
+    if (sslProtocol != null) {
+      builder.sslProtocol(sslProtocol);
+    }
+    return builder;
+  }
+
+  protected static SessionPool.Builder configureSsl(SessionPool.Builder 
builder) {
+    builder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd);
+    if (sslProtocol != null) {
+      builder.sslProtocol(sslProtocol);
+    }
+    return builder;
+  }
+
+  protected static TableSessionBuilder configureSsl(TableSessionBuilder 
builder) {
+    builder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd);
+    if (sslProtocol != null) {
+      builder.sslProtocol(sslProtocol);
+    }
+    return builder;
+  }
+
+  protected static TableSessionPoolBuilder 
configureSsl(TableSessionPoolBuilder builder) {
+    builder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd);
+    if (sslProtocol != null) {
+      builder.sslProtocol(sslProtocol);
+    }
+    return builder;
+  }
+
   protected static String checkRequiredArg(
       String arg, String name, CommandLine commandLine, String defaultValue)
       throws ArgsErrorException {
@@ -170,6 +206,7 @@ public abstract class AbstractDataTool {
     String useSslStr = commandLine.getOptionValue(Constants.USE_SSL_ARGS);
     useSsl = Boolean.parseBoolean(useSslStr);
     if (useSsl) {
+      sslProtocol = commandLine.getOptionValue(Constants.SSL_PROTOCOL_ARGS);
       String givenTS = commandLine.getOptionValue(Constants.TRUST_STORE_ARGS);
       if (givenTS != null) {
         trustStore = givenTS;
diff --git 
a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ExportDataTable.java
 
b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ExportDataTable.java
index dcf05baa14e..458c447ba4f 100644
--- 
a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ExportDataTable.java
+++ 
b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ExportDataTable.java
@@ -71,8 +71,7 @@ public class ExportDataTable extends AbstractExportData {
             .database(database)
             .thriftMaxFrameSize(rpcMaxFrameSize);
     if (useSsl) {
-      tableSessionBuilder =
-          
tableSessionBuilder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd);
+      tableSessionBuilder = configureSsl(tableSessionBuilder);
     }
     tableSession = tableSessionBuilder.build();
     SessionDataSet sessionDataSet = tableSession.executeQueryStatement("show 
databases", timeout);
diff --git 
a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ExportDataTree.java 
b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ExportDataTree.java
index 9d7d0ca521d..fd8aeb0cbe3 100644
--- 
a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ExportDataTree.java
+++ 
b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ExportDataTree.java
@@ -80,8 +80,7 @@ public class ExportDataTree extends AbstractExportData {
             .enableRedirection(SessionConfig.DEFAULT_REDIRECTION_MODE)
             .version(SessionConfig.DEFAULT_VERSION);
     if (useSsl) {
-      sessionBuilder =
-          
sessionBuilder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd);
+      sessionBuilder = configureSsl(sessionBuilder);
     }
     session = sessionBuilder.build();
     session.open(false);
diff --git 
a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTable.java
 
b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTable.java
index 506da8b8e17..d103c63555b 100644
--- 
a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTable.java
+++ 
b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTable.java
@@ -88,8 +88,7 @@ public class ImportDataTable extends AbstractImportData {
             .enableAutoFetch(false)
             .database(database);
     if (useSsl) {
-      tableSessionPoolBuilder =
-          
tableSessionPoolBuilder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd);
+      tableSessionPoolBuilder = configureSsl(tableSessionPoolBuilder);
     }
     sessionPool = tableSessionPoolBuilder.build();
     final File file = new File(targetPath);
diff --git 
a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTree.java 
b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTree.java
index 95aa9263142..c976e847740 100644
--- 
a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTree.java
+++ 
b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/data/ImportDataTree.java
@@ -72,8 +72,7 @@ public class ImportDataTree extends AbstractImportData {
             .enableRedirection(false)
             .enableAutoFetch(false);
     if (useSsl) {
-      sessionPoolBuilder =
-          
sessionPoolBuilder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd);
+      sessionPoolBuilder = configureSsl(sessionPoolBuilder);
     }
     sessionPool = sessionPoolBuilder.build();
     sessionPool.setEnableQueryRedirection(false);
diff --git 
a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/AbstractSchemaTool.java
 
b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/AbstractSchemaTool.java
index 09442bdab87..2bee5f5d331 100644
--- 
a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/AbstractSchemaTool.java
+++ 
b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/AbstractSchemaTool.java
@@ -25,6 +25,8 @@ import org.apache.iotdb.cli.utils.IoTPrinter;
 import org.apache.iotdb.cli.utils.JlineUtils;
 import org.apache.iotdb.exception.ArgsErrorException;
 import org.apache.iotdb.session.Session;
+import org.apache.iotdb.session.pool.SessionPool;
+import org.apache.iotdb.session.pool.TableSessionPoolBuilder;
 import org.apache.iotdb.tool.common.Constants;
 
 import org.apache.commons.cli.CommandLine;
@@ -53,6 +55,7 @@ public abstract class AbstractSchemaTool {
   protected static Boolean useSsl;
   protected static String trustStore;
   protected static String trustStorePwd;
+  protected static String sslProtocol;
   protected static Session session;
   protected static String queryPath;
   protected static int threadNum = 8;
@@ -73,6 +76,30 @@ public abstract class AbstractSchemaTool {
 
   protected AbstractSchemaTool() {}
 
+  protected static Session.Builder configureSsl(Session.Builder builder) {
+    builder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd);
+    if (sslProtocol != null) {
+      builder.sslProtocol(sslProtocol);
+    }
+    return builder;
+  }
+
+  protected static SessionPool.Builder configureSsl(SessionPool.Builder 
builder) {
+    builder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd);
+    if (sslProtocol != null) {
+      builder.sslProtocol(sslProtocol);
+    }
+    return builder;
+  }
+
+  protected static TableSessionPoolBuilder 
configureSsl(TableSessionPoolBuilder builder) {
+    builder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd);
+    if (sslProtocol != null) {
+      builder.sslProtocol(sslProtocol);
+    }
+    return builder;
+  }
+
   protected static String checkRequiredArg(
       String arg, String name, CommandLine commandLine, String defaultValue)
       throws ArgsErrorException {
@@ -107,6 +134,7 @@ public abstract class AbstractSchemaTool {
     String useSslStr = commandLine.getOptionValue(Constants.USE_SSL_ARGS);
     useSsl = Boolean.parseBoolean(useSslStr);
     if (useSsl) {
+      sslProtocol = commandLine.getOptionValue(Constants.SSL_PROTOCOL_ARGS);
       String givenTS = commandLine.getOptionValue(Constants.TRUST_STORE_ARGS);
       if (givenTS != null) {
         trustStore = givenTS;
diff --git 
a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ExportSchemaTable.java
 
b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ExportSchemaTable.java
index 1ed3e2c6b86..c9b15870d21 100644
--- 
a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ExportSchemaTable.java
+++ 
b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ExportSchemaTable.java
@@ -64,8 +64,7 @@ public class ExportSchemaTable extends AbstractExportSchema {
             .enableAutoFetch(false)
             .database(database);
     if (useSsl) {
-      tableSessionPoolBuilder =
-          
tableSessionPoolBuilder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd);
+      tableSessionPoolBuilder = configureSsl(tableSessionPoolBuilder);
     }
     sessionPool = tableSessionPoolBuilder.build();
     checkDatabase();
diff --git 
a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ExportSchemaTree.java
 
b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ExportSchemaTree.java
index 334d8a8d8dc..da304f87c49 100644
--- 
a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ExportSchemaTree.java
+++ 
b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ExportSchemaTree.java
@@ -51,8 +51,7 @@ public class ExportSchemaTree extends AbstractExportSchema {
             .username(username)
             .password(password);
     if (useSsl) {
-      sessionBuilder =
-          
sessionBuilder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd);
+      sessionBuilder = configureSsl(sessionBuilder);
     }
     session = sessionBuilder.build();
     session.open(false);
diff --git 
a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ImportSchemaTable.java
 
b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ImportSchemaTable.java
index 011042c34d2..004ec8b4152 100644
--- 
a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ImportSchemaTable.java
+++ 
b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ImportSchemaTable.java
@@ -60,8 +60,7 @@ public class ImportSchemaTable extends AbstractImportSchema {
             .enableAutoFetch(false)
             .database(database);
     if (useSsl) {
-      tableSessionPoolBuilder =
-          
tableSessionPoolBuilder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd);
+      tableSessionPoolBuilder = configureSsl(tableSessionPoolBuilder);
     }
     sessionPool = tableSessionPoolBuilder.build();
     final File file = new File(targetPath);
diff --git 
a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ImportSchemaTree.java
 
b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ImportSchemaTree.java
index 9526447fd96..5d7dfc35d8a 100644
--- 
a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ImportSchemaTree.java
+++ 
b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/schema/ImportSchemaTree.java
@@ -73,8 +73,7 @@ public class ImportSchemaTree extends AbstractImportSchema {
             .enableRedirection(false)
             .enableAutoFetch(false);
     if (useSsl) {
-      sessionPoolBuilder =
-          
sessionPoolBuilder.useSSL(true).trustStore(trustStore).trustStorePwd(trustStorePwd);
+      sessionPoolBuilder = configureSsl(sessionPoolBuilder);
     }
     sessionPool = sessionPoolBuilder.build();
     sessionPool.setEnableQueryRedirection(false);
diff --git 
a/iotdb-client/isession/src/main/java/org/apache/iotdb/isession/SessionConfig.java
 
b/iotdb-client/isession/src/main/java/org/apache/iotdb/isession/SessionConfig.java
index 611014c615c..7885d50cf5d 100644
--- 
a/iotdb-client/isession/src/main/java/org/apache/iotdb/isession/SessionConfig.java
+++ 
b/iotdb-client/isession/src/main/java/org/apache/iotdb/isession/SessionConfig.java
@@ -56,5 +56,7 @@ public class SessionConfig {
 
   public static final String SQL_DIALECT = "tree";
 
+  public static final String DEFAULT_SSL_PROTOCOL = "TLS";
+
   private SessionConfig() {}
 }
diff --git a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Config.java 
b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Config.java
index 0b1049330ea..d79656cc8d2 100644
--- a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Config.java
+++ b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Config.java
@@ -82,6 +82,10 @@ public class Config {
 
   public static final String TRUST_STORE_PWD = "trust_store_pwd";
 
+  public static final String SSL_PROTOCOL = "ssl_protocol";
+
+  static final String DEFAULT_SSL_PROTOCOL = "TLS";
+
   public static final String SQL_DIALECT = "sql_dialect";
 
   public static final String DATABASE = "db";
diff --git 
a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnection.java 
b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnection.java
index 7f37e2206fb..0dc81115dd0 100644
--- a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnection.java
+++ b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnection.java
@@ -544,12 +544,13 @@ public class IoTDBConnection implements Connection {
 
     if (params.isUseSSL()) {
       transport =
-          DeepCopyRpcTransportFactory.INSTANCE.getTransport(
+          DeepCopyRpcTransportFactory.INSTANCE.getTransportWithSSLConfig(
               params.getHost(),
               params.getPort(),
               getNetworkTimeout(),
               params.getTrustStore(),
-              params.getTrustStorePwd());
+              params.getTrustStorePwd(),
+              params.getSslProtocol());
     } else {
       transport =
           DeepCopyRpcTransportFactory.INSTANCE.getTransport(
diff --git 
a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnectionParams.java
 
b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnectionParams.java
index 1112caabd4e..8bf51379c5c 100644
--- 
a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnectionParams.java
+++ 
b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnectionParams.java
@@ -51,6 +51,7 @@ public class IoTDBConnectionParams {
   private boolean useSSL = false;
   private String trustStore;
   private String trustStorePwd;
+  private String sslProtocol = Config.DEFAULT_SSL_PROTOCOL;
 
   private String sqlDialect = TREE;
 
@@ -184,6 +185,14 @@ public class IoTDBConnectionParams {
     this.trustStorePwd = trustStorePwd;
   }
 
+  public String getSslProtocol() {
+    return sslProtocol;
+  }
+
+  public void setSslProtocol(String sslProtocol) {
+    this.sslProtocol = sslProtocol;
+  }
+
   public String getSqlDialect() {
     return sqlDialect;
   }
diff --git a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Utils.java 
b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Utils.java
index 00e46cc340d..ea205ef7267 100644
--- a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Utils.java
+++ b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/Utils.java
@@ -19,6 +19,8 @@
 
 package org.apache.iotdb.jdbc;
 
+import org.apache.iotdb.rpc.RpcSslUtils;
+
 import java.nio.charset.Charset;
 import java.time.DateTimeException;
 import java.time.ZoneId;
@@ -136,6 +138,9 @@ public class Utils {
     if (info.containsKey(Config.TRUST_STORE_PWD)) {
       params.setTrustStorePwd(info.getProperty(Config.TRUST_STORE_PWD));
     }
+    if (info.containsKey(Config.SSL_PROTOCOL)) {
+      
params.setSslProtocol(RpcSslUtils.normalizeProtocol(info.getProperty(Config.SSL_PROTOCOL)));
+    }
     if (info.containsKey(Config.SQL_DIALECT)) {
       params.setSqlDialect(info.getProperty(Config.SQL_DIALECT));
     }
@@ -175,6 +180,7 @@ public class Utils {
         case Config.USE_SSL:
         case Config.TRUST_STORE:
         case Config.TRUST_STORE_PWD:
+        case Config.SSL_PROTOCOL:
         case Config.VERSION:
         case Config.NETWORK_TIMEOUT:
         case Config.SQL_DIALECT:
diff --git 
a/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/UtilsTest.java 
b/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/UtilsTest.java
index 4c401b88017..d201a9b2d45 100644
--- a/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/UtilsTest.java
+++ b/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/UtilsTest.java
@@ -159,4 +159,15 @@ public class UtilsTest {
     Utils.parseUrl("jdbc:iotdb://127.0.0.1:6667?rpc_compress=true", 
properties);
     assertTrue(Config.rpcThriftCompressionEnable);
   }
+
+  @Test
+  public void testParseSslConfig() throws IoTDBURLException {
+    Properties properties = new Properties();
+    IoTDBConnectionParams params =
+        Utils.parseUrl(
+            
"jdbc:iotdb://127.0.0.1:6667?use_ssl=true&ssl_protocol=ProviderProtocol", 
properties);
+
+    assertTrue(params.isUseSSL());
+    assertEquals("ProviderProtocol", params.getSslProtocol());
+  }
 }
diff --git 
a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/BaseRpcTransportFactory.java
 
b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/BaseRpcTransportFactory.java
index 22e104b6a58..03bf2070bca 100644
--- 
a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/BaseRpcTransportFactory.java
+++ 
b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/BaseRpcTransportFactory.java
@@ -83,9 +83,15 @@ public class BaseRpcTransportFactory extends 
TTransportFactory {
   public TTransport getTransport(
       String ip, int port, int timeout, String trustStore, String 
trustStorePwd)
       throws TTransportException {
+    return getTransportWithSSLConfig(ip, port, timeout, trustStore, 
trustStorePwd, null);
+  }
+
+  public TTransport getTransportWithSSLConfig(
+      String ip, int port, int timeout, String trustStore, String 
trustStorePwd, String sslProtocol)
+      throws TTransportException {
     TSSLTransportFactory.TSSLTransportParameters params =
-        new TSSLTransportFactory.TSSLTransportParameters();
-    params.setTrustStore(trustStore, trustStorePwd);
+        RpcSslUtils.createTSSLTransportParameters(sslProtocol);
+    RpcSslUtils.setTrustStore(params, trustStore, trustStorePwd);
     TTransport transport = TSSLTransportFactory.getClientSocket(ip, port, 
timeout, params);
     return inner.getTransport(transport);
   }
@@ -99,11 +105,24 @@ public class BaseRpcTransportFactory extends 
TTransportFactory {
       String keyStore,
       String keyStorePwd)
       throws TTransportException {
+    return getTransport(ip, port, timeout, trustStore, trustStorePwd, 
keyStore, keyStorePwd, null);
+  }
+
+  public TTransport getTransport(
+      String ip,
+      int port,
+      int timeout,
+      String trustStore,
+      String trustStorePwd,
+      String keyStore,
+      String keyStorePwd,
+      String sslProtocol)
+      throws TTransportException {
     TSSLTransportFactory.TSSLTransportParameters params =
-        new TSSLTransportFactory.TSSLTransportParameters();
+        RpcSslUtils.createTSSLTransportParameters(sslProtocol);
     if (Files.exists(Paths.get(trustStore)) && 
Files.exists(Paths.get(keyStore))) {
-      params.setTrustStore(trustStore, trustStorePwd);
-      params.setKeyStore(keyStore, keyStorePwd);
+      RpcSslUtils.setTrustStore(params, trustStore, trustStorePwd);
+      RpcSslUtils.setKeyStore(params, keyStore, keyStorePwd);
     } else {
       throw new TTransportException(new 
IOException(RpcMessages.COULD_NOT_LOAD_KEYSTORE));
     }
diff --git 
a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/RpcSslUtils.java 
b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/RpcSslUtils.java
new file mode 100644
index 00000000000..c6ceb5b4c5d
--- /dev/null
+++ 
b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/RpcSslUtils.java
@@ -0,0 +1,245 @@
+/*
+ * 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.iotdb.rpc;
+
+import org.apache.thrift.transport.TSSLTransportFactory;
+import org.apache.thrift.transport.TTransportException;
+
+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.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.AccessDeniedException;
+import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
+import java.nio.file.Path;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.stream.Stream;
+
+public final class RpcSslUtils {
+
+  private static final String DEFAULT_PROTOCOL = "TLS";
+  private static final String PKCS12_STORE_TYPE = "PKCS12";
+  private static final String JKS_STORE_TYPE = "JKS";
+
+  private static volatile String protocol = DEFAULT_PROTOCOL;
+
+  private RpcSslUtils() {}
+
+  public static void configure(String sslProtocol) {
+    protocol = normalizeProtocol(sslProtocol);
+  }
+
+  public static TSSLTransportFactory.TSSLTransportParameters 
createTSSLTransportParameters() {
+    return createTSSLTransportParameters(protocol);
+  }
+
+  public static TSSLTransportFactory.TSSLTransportParameters 
createTSSLTransportParameters(
+      String sslProtocol) {
+    return new 
TSSLTransportFactory.TSSLTransportParameters(normalizeProtocol(sslProtocol), 
null);
+  }
+
+  public static void setKeyStore(
+      TSSLTransportFactory.TSSLTransportParameters params, String 
keyStorePath, String keyStorePwd)
+      throws TTransportException {
+    try {
+      params.setKeyStore(
+          keyStorePath,
+          keyStorePwd,
+          KeyManagerFactory.getDefaultAlgorithm(),
+          detectStoreType(keyStorePath, keyStorePwd));
+    } catch (GeneralSecurityException | IOException e) {
+      throw new TTransportException(e);
+    }
+  }
+
+  public static void setTrustStore(
+      TSSLTransportFactory.TSSLTransportParameters params,
+      String trustStorePath,
+      String trustStorePwd)
+      throws TTransportException {
+    try {
+      params.setTrustStore(
+          trustStorePath,
+          trustStorePwd,
+          TrustManagerFactory.getDefaultAlgorithm(),
+          detectStoreType(trustStorePath, trustStorePwd));
+    } catch (GeneralSecurityException | IOException e) {
+      throw new TTransportException(e);
+    }
+  }
+
+  public static SSLContext createSSLContext(
+      String keyStorePath,
+      String keyStorePassword,
+      String trustStorePath,
+      String trustStorePassword)
+      throws GeneralSecurityException, IOException {
+    return createSSLContext(
+        keyStorePath, keyStorePassword, trustStorePath, trustStorePassword, 
protocol);
+  }
+
+  public static SSLContext createSSLContext(
+      String keyStorePath,
+      String keyStorePassword,
+      String trustStorePath,
+      String trustStorePassword,
+      String sslProtocol)
+      throws GeneralSecurityException, IOException {
+    SSLContext context = 
SSLContext.getInstance(normalizeProtocol(sslProtocol));
+    KeyManager[] keyManagers =
+        hasText(keyStorePath) ? loadKeyManagers(keyStorePath, 
keyStorePassword) : null;
+    TrustManager[] trustManagers =
+        hasText(trustStorePath) ? loadTrustManagers(trustStorePath, 
trustStorePassword) : null;
+    context.init(keyManagers, trustManagers, null);
+    return context;
+  }
+
+  public static KeyManager[] createKeyManagers(String keyStorePath, String 
keyStorePassword)
+      throws GeneralSecurityException, IOException {
+    return loadKeyManagers(keyStorePath, keyStorePassword);
+  }
+
+  public static TrustManager[] createTrustManagers(String trustStorePath, 
String trustStorePassword)
+      throws GeneralSecurityException, IOException {
+    return loadTrustManagers(trustStorePath, trustStorePassword);
+  }
+
+  public static String getProtocol() {
+    return protocol;
+  }
+
+  public static void validateKeyStore(String keyStorePath, String 
keyStorePassword)
+      throws TTransportException {
+    validateStore(keyStorePath, keyStorePassword);
+  }
+
+  public static void validateTrustStore(String trustStorePath, String 
trustStorePassword)
+      throws TTransportException {
+    validateStore(trustStorePath, trustStorePassword);
+  }
+
+  private static KeyManager[] loadKeyManagers(String keyStorePath, String 
keyStorePassword)
+      throws GeneralSecurityException, IOException {
+    KeyStore keyStore = loadStore(keyStorePath, keyStorePassword);
+    KeyManagerFactory kmf = 
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+    kmf.init(keyStore, toPassword(keyStorePassword));
+    return kmf.getKeyManagers();
+  }
+
+  private static TrustManager[] loadTrustManagers(String trustStorePath, 
String trustStorePassword)
+      throws GeneralSecurityException, IOException {
+    KeyStore trustStore = loadStore(trustStorePath, trustStorePassword);
+    TrustManagerFactory tmf =
+        
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+    tmf.init(trustStore);
+    return tmf.getTrustManagers();
+  }
+
+  private static String detectStoreType(String storePath, String storePassword)
+      throws GeneralSecurityException, IOException {
+    return loadStore(storePath, storePassword).getType();
+  }
+
+  private static KeyStore loadStore(String storePath, String storePassword)
+      throws GeneralSecurityException, IOException {
+    Exception lastException = null;
+    for (String storeType : storeTypeCandidates()) {
+      try {
+        return loadStore(storePath, storePassword, storeType);
+      } catch (AccessDeniedException | FileNotFoundException e) {
+        throw e;
+      } catch (GeneralSecurityException | IOException e) {
+        lastException = e;
+      }
+    }
+    if (lastException instanceof GeneralSecurityException) {
+      throw (GeneralSecurityException) lastException;
+    }
+    if (lastException instanceof IOException) {
+      throw (IOException) lastException;
+    }
+    throw new IOException("No supported keystore or truststore type is 
available");
+  }
+
+  private static KeyStore loadStore(String storePath, String storePassword, 
String storeType)
+      throws GeneralSecurityException, IOException {
+    KeyStore store = KeyStore.getInstance(storeType);
+    try (InputStream inputStream = Files.newInputStream(Path.of(storePath))) {
+      store.load(inputStream, toPassword(storePassword));
+    } catch (AccessDeniedException e) {
+      throw new AccessDeniedException("Failed to load keystore or truststore 
file");
+    } catch (FileNotFoundException | NoSuchFileException e) {
+      throw new FileNotFoundException("keystore or truststore file not found: 
" + storePath);
+    }
+    return store;
+  }
+
+  private static void validateStore(String storePath, String storePassword)
+      throws TTransportException {
+    try {
+      KeyStore store = loadStore(storePath, storePassword);
+      Enumeration<String> aliases = store.aliases();
+      while (aliases.hasMoreElements()) {
+        X509Certificate cert = (X509Certificate) 
store.getCertificate(aliases.nextElement());
+        if (cert != null) {
+          cert.checkValidity();
+        }
+      }
+    } catch (Exception e) {
+      throw new TTransportException(e);
+    }
+  }
+
+  private static char[] toPassword(String password) {
+    return password == null ? null : password.toCharArray();
+  }
+
+  public static String normalizeProtocol(String value) {
+    String trimmed = trimToEmpty(value);
+    return trimmed.isEmpty() ? DEFAULT_PROTOCOL : trimmed;
+  }
+
+  private static String trimToEmpty(String value) {
+    return value == null ? "" : value.trim();
+  }
+
+  private static boolean hasText(String value) {
+    return value != null && !value.trim().isEmpty();
+  }
+
+  private static String[] storeTypeCandidates() {
+    return Stream.of(KeyStore.getDefaultType(), PKCS12_STORE_TYPE, 
JKS_STORE_TYPE)
+        .map(String::trim)
+        .map(s -> s.toUpperCase(Locale.ROOT))
+        .filter(s -> !s.isEmpty())
+        .distinct()
+        .toArray(String[]::new);
+  }
+}
diff --git 
a/iotdb-client/service-rpc/src/test/java/org/apache/iotdb/rpc/RpcUtilsTest.java 
b/iotdb-client/service-rpc/src/test/java/org/apache/iotdb/rpc/RpcUtilsTest.java
index 940c50453a2..143de1d9ab7 100644
--- 
a/iotdb-client/service-rpc/src/test/java/org/apache/iotdb/rpc/RpcUtilsTest.java
+++ 
b/iotdb-client/service-rpc/src/test/java/org/apache/iotdb/rpc/RpcUtilsTest.java
@@ -99,4 +99,11 @@ public class RpcUtilsTest {
       Assert.assertTrue(e.getMessage().contains("failed"));
     }
   }
+
+  @Test
+  public void testSslProtocolNormalization() {
+    Assert.assertEquals("TLS", RpcSslUtils.normalizeProtocol(null));
+    Assert.assertEquals("TLSv1.3", RpcSslUtils.normalizeProtocol(" TLSv1.3 "));
+    Assert.assertEquals("ProviderProtocol", RpcSslUtils.normalizeProtocol(" 
ProviderProtocol "));
+  }
 }
diff --git 
a/iotdb-client/session/src/main/java/org/apache/iotdb/session/AbstractSessionBuilder.java
 
b/iotdb-client/session/src/main/java/org/apache/iotdb/session/AbstractSessionBuilder.java
index f410b167463..873e6dd248d 100644
--- 
a/iotdb-client/session/src/main/java/org/apache/iotdb/session/AbstractSessionBuilder.java
+++ 
b/iotdb-client/session/src/main/java/org/apache/iotdb/session/AbstractSessionBuilder.java
@@ -63,6 +63,7 @@ public abstract class AbstractSessionBuilder {
   public boolean useSSL = false;
   public String trustStore;
   public String trustStorePwd;
+  public String sslProtocol = SessionConfig.DEFAULT_SSL_PROTOCOL;
 
   // max retry count, if set to 0, means that we won't do any retry
   // we can use any available DataNodes(fetched in background thread if 
enableAutoFetch is true,
diff --git 
a/iotdb-client/session/src/main/java/org/apache/iotdb/session/NodesSupplier.java
 
b/iotdb-client/session/src/main/java/org/apache/iotdb/session/NodesSupplier.java
index d57844b4997..a41db581e9c 100644
--- 
a/iotdb-client/session/src/main/java/org/apache/iotdb/session/NodesSupplier.java
+++ 
b/iotdb-client/session/src/main/java/org/apache/iotdb/session/NodesSupplier.java
@@ -61,6 +61,7 @@ public class NodesSupplier implements INodeSupplier, Runnable 
{
   private final boolean useSSL;
   private final String trustStore;
   private final String trustStorePwd;
+  private final String sslProtocol;
   private final boolean enableRPCCompression;
   private final String userName;
 
@@ -95,6 +96,7 @@ public class NodesSupplier implements INodeSupplier, Runnable 
{
       boolean useSSL,
       String trustStore,
       String trustStorePwd,
+      String sslProtocol,
       boolean enableRPCCompression,
       String version) {
 
@@ -110,6 +112,7 @@ public class NodesSupplier implements INodeSupplier, 
Runnable {
             useSSL,
             trustStore,
             trustStorePwd,
+            sslProtocol,
             enableRPCCompression,
             version);
 
@@ -132,6 +135,7 @@ public class NodesSupplier implements INodeSupplier, 
Runnable {
       boolean useSSL,
       String trustStore,
       String trustStorePwd,
+      String sslProtocol,
       boolean enableRPCCompression,
       String version) {
     this.availableNodes.addAll(new HashSet<>(endPointList));
@@ -140,6 +144,7 @@ public class NodesSupplier implements INodeSupplier, 
Runnable {
     this.useSSL = useSSL;
     this.trustStore = trustStore;
     this.trustStorePwd = trustStorePwd;
+    this.sslProtocol = sslProtocol;
     this.enableRPCCompression = enableRPCCompression;
     this.zoneId = zoneId == null ? ZoneId.systemDefault() : zoneId;
     this.thriftDefaultBufferSize = thriftDefaultBufferSize;
@@ -188,6 +193,7 @@ public class NodesSupplier implements INodeSupplier, 
Runnable {
           useSSL,
           trustStore,
           trustStorePwd,
+          sslProtocol,
           userName,
           password,
           enableRPCCompression,
diff --git 
a/iotdb-client/session/src/main/java/org/apache/iotdb/session/Session.java 
b/iotdb-client/session/src/main/java/org/apache/iotdb/session/Session.java
index f352a0612e6..648a63845b4 100644
--- a/iotdb-client/session/src/main/java/org/apache/iotdb/session/Session.java
+++ b/iotdb-client/session/src/main/java/org/apache/iotdb/session/Session.java
@@ -134,6 +134,7 @@ public class Session implements ISession {
   protected boolean useSSL;
   protected String trustStore;
   protected String trustStorePwd;
+  protected String sslProtocol;
 
   /**
    * Timeout of query can be set by users. A negative number means using the 
default configuration
@@ -474,6 +475,7 @@ public class Session implements ISession {
     this.useSSL = builder.useSSL;
     this.trustStore = builder.trustStore;
     this.trustStorePwd = builder.trustStorePwd;
+    this.sslProtocol = builder.sslProtocol;
     this.enableAutoFetch = builder.enableAutoFetch;
     this.maxRetryCount = builder.maxRetryCount;
     this.retryIntervalInMs = builder.retryIntervalInMs;
@@ -543,6 +545,7 @@ public class Session implements ISession {
               useSSL,
               trustStore,
               trustStorePwd,
+              sslProtocol,
               enableRPCCompaction,
               version.toString());
     } else {
@@ -4435,6 +4438,11 @@ public class Session implements ISession {
       return this;
     }
 
+    public Builder sslProtocol(String sslProtocol) {
+      this.sslProtocol = sslProtocol;
+      return this;
+    }
+
     public Session build() {
       if (nodeUrls != null
           && (!SessionConfig.DEFAULT_HOST.equals(host) || rpcPort != 
SessionConfig.DEFAULT_PORT)) {
diff --git 
a/iotdb-client/session/src/main/java/org/apache/iotdb/session/SessionConnection.java
 
b/iotdb-client/session/src/main/java/org/apache/iotdb/session/SessionConnection.java
index c3e62cdd3e9..468b59abb0c 100644
--- 
a/iotdb-client/session/src/main/java/org/apache/iotdb/session/SessionConnection.java
+++ 
b/iotdb-client/session/src/main/java/org/apache/iotdb/session/SessionConnection.java
@@ -152,7 +152,8 @@ public class SessionConnection {
     this.sqlDialect = sqlDialect;
     this.database = database;
     try {
-      init(endPoint, session.useSSL, session.trustStore, 
session.trustStorePwd);
+      init(
+          endPoint, session.useSSL, session.trustStore, session.trustStorePwd, 
session.sslProtocol);
     } catch (StatementExecutionException e) {
       throw new IoTDBConnectionException(e.getMessage());
     } catch (IoTDBConnectionException e) {
@@ -180,7 +181,12 @@ public class SessionConnection {
     initClusterConn();
   }
 
-  private void init(TEndPoint endPoint, boolean useSSL, String trustStore, 
String trustStorePwd)
+  private void init(
+      TEndPoint endPoint,
+      boolean useSSL,
+      String trustStore,
+      String trustStorePwd,
+      String sslProtocol)
       throws IoTDBConnectionException, StatementExecutionException {
     
DeepCopyRpcTransportFactory.setDefaultBufferCapacity(session.thriftDefaultBufferSize);
     
DeepCopyRpcTransportFactory.setThriftMaxFrameSize(session.thriftMaxFrameSize);
@@ -190,12 +196,13 @@ public class SessionConnection {
       }
       if (useSSL) {
         transport =
-            DeepCopyRpcTransportFactory.INSTANCE.getTransport(
+            DeepCopyRpcTransportFactory.INSTANCE.getTransportWithSSLConfig(
                 endPoint.getIp(),
                 endPoint.getPort(),
                 session.connectionTimeoutInMs,
                 trustStore,
-                trustStorePwd);
+                trustStorePwd,
+                sslProtocol);
       } else {
         transport =
             DeepCopyRpcTransportFactory.INSTANCE.getTransport(
@@ -266,7 +273,12 @@ public class SessionConnection {
     for (TEndPoint tEndPoint : endPointList) {
       try {
         session.defaultEndPoint = tEndPoint;
-        init(tEndPoint, session.useSSL, session.trustStore, 
session.trustStorePwd);
+        init(
+            tEndPoint,
+            session.useSSL,
+            session.trustStore,
+            session.trustStorePwd,
+            session.sslProtocol);
       } catch (IoTDBConnectionException e) {
         if (!reconnect()) {
           logger.error(SessionMessages.CLUSTER_NO_NODES);
@@ -1083,7 +1095,12 @@ public class SessionConnection {
           }
           tryHostNum++;
           try {
-            init(endPoint, session.useSSL, session.trustStore, 
session.trustStorePwd);
+            init(
+                endPoint,
+                session.useSSL,
+                session.trustStore,
+                session.trustStorePwd,
+                session.sslProtocol);
             connectedSuccess = true;
           } catch (IoTDBConnectionException e) {
             logger.warn(SessionMessages.NODE_DOWN_TRY_NEXT, endPoint);
diff --git 
a/iotdb-client/session/src/main/java/org/apache/iotdb/session/TableSessionBuilder.java
 
b/iotdb-client/session/src/main/java/org/apache/iotdb/session/TableSessionBuilder.java
index be53797165a..e724c0fd532 100644
--- 
a/iotdb-client/session/src/main/java/org/apache/iotdb/session/TableSessionBuilder.java
+++ 
b/iotdb-client/session/src/main/java/org/apache/iotdb/session/TableSessionBuilder.java
@@ -239,6 +239,18 @@ public class TableSessionBuilder extends 
AbstractSessionBuilder {
     return this;
   }
 
+  /**
+   * Sets the SSL protocol for secure connections.
+   *
+   * @param sslProtocol the SSL protocol.
+   * @return the current {@link TableSessionBuilder} instance.
+   * @defaultValue TLS
+   */
+  public TableSessionBuilder sslProtocol(String sslProtocol) {
+    this.sslProtocol = sslProtocol;
+    return this;
+  }
+
   /**
    * Enables or disables rpc compression for the connection.
    *
diff --git 
a/iotdb-client/session/src/main/java/org/apache/iotdb/session/ThriftConnection.java
 
b/iotdb-client/session/src/main/java/org/apache/iotdb/session/ThriftConnection.java
index e3b9e8fc989..3ab3abd581d 100644
--- 
a/iotdb-client/session/src/main/java/org/apache/iotdb/session/ThriftConnection.java
+++ 
b/iotdb-client/session/src/main/java/org/apache/iotdb/session/ThriftConnection.java
@@ -78,6 +78,7 @@ public class ThriftConnection {
       boolean useSSL,
       String trustStore,
       String trustStorePwd,
+      String sslProtocol,
       String username,
       String password,
       boolean enableRPCCompression,
@@ -89,12 +90,13 @@ public class ThriftConnection {
     try {
       if (useSSL) {
         transport =
-            DeepCopyRpcTransportFactory.INSTANCE.getTransport(
+            DeepCopyRpcTransportFactory.INSTANCE.getTransportWithSSLConfig(
                 endPoint.getIp(),
                 endPoint.getPort(),
                 connectionTimeoutInMs,
                 trustStore,
-                trustStorePwd);
+                trustStorePwd,
+                sslProtocol);
       } else {
         transport =
             DeepCopyRpcTransportFactory.INSTANCE.getTransport(
diff --git 
a/iotdb-client/session/src/main/java/org/apache/iotdb/session/pool/SessionPool.java
 
b/iotdb-client/session/src/main/java/org/apache/iotdb/session/pool/SessionPool.java
index 3eaabe7f1fa..8136b2be68f 100644
--- 
a/iotdb-client/session/src/main/java/org/apache/iotdb/session/pool/SessionPool.java
+++ 
b/iotdb-client/session/src/main/java/org/apache/iotdb/session/pool/SessionPool.java
@@ -116,6 +116,9 @@ public class SessionPool implements ISessionPool {
   private String trustStore;
 
   private String trustStorePwd;
+
+  private String sslProtocol = SessionConfig.DEFAULT_SSL_PROTOCOL;
+
   private ZoneId zoneId;
   // this field only take effect in write request, nothing to do with any 
other type requests,
   // like query, load and so on.
@@ -466,6 +469,7 @@ public class SessionPool implements ISessionPool {
     this.useSSL = useSSL;
     this.trustStore = trustStore;
     this.trustStorePwd = trustStorePwd;
+    this.sslProtocol = SessionConfig.DEFAULT_SSL_PROTOCOL;
     initThreadPool();
     initAvailableNodes(Collections.singletonList(new TEndPoint(host, port)));
   }
@@ -536,6 +540,7 @@ public class SessionPool implements ISessionPool {
     this.useSSL = builder.useSSL;
     this.trustStore = builder.trustStore;
     this.trustStorePwd = builder.trustStorePwd;
+    this.sslProtocol = builder.sslProtocol;
     this.maxRetryCount = builder.maxRetryCount;
     this.retryIntervalInMs = builder.retryIntervalInMs;
     this.sqlDialect = builder.sqlDialect;
@@ -593,6 +598,7 @@ public class SessionPool implements ISessionPool {
               .useSSL(useSSL)
               .trustStore(trustStore)
               .trustStorePwd(trustStorePwd)
+              .sslProtocol(sslProtocol)
               .maxRetryCount(maxRetryCount)
               .retryIntervalInMs(retryIntervalInMs)
               .sqlDialect(sqlDialect)
@@ -618,6 +624,7 @@ public class SessionPool implements ISessionPool {
               .useSSL(useSSL)
               .trustStore(trustStore)
               .trustStorePwd(trustStorePwd)
+              .sslProtocol(sslProtocol)
               .maxRetryCount(maxRetryCount)
               .retryIntervalInMs(retryIntervalInMs)
               .sqlDialect(sqlDialect)
@@ -662,6 +669,7 @@ public class SessionPool implements ISessionPool {
             useSSL,
             trustStore,
             trustStorePwd,
+            sslProtocol,
             enableThriftCompression,
             version.toString());
   }
@@ -3637,6 +3645,11 @@ public class SessionPool implements ISessionPool {
       return this;
     }
 
+    public Builder sslProtocol(String sslProtocol) {
+      this.sslProtocol = sslProtocol;
+      return this;
+    }
+
     public Builder host(String host) {
       this.host = host;
       return this;
diff --git 
a/iotdb-client/session/src/main/java/org/apache/iotdb/session/pool/TableSessionPoolBuilder.java
 
b/iotdb-client/session/src/main/java/org/apache/iotdb/session/pool/TableSessionPoolBuilder.java
index d5f52f3a8dc..2c7aba1a452 100644
--- 
a/iotdb-client/session/src/main/java/org/apache/iotdb/session/pool/TableSessionPoolBuilder.java
+++ 
b/iotdb-client/session/src/main/java/org/apache/iotdb/session/pool/TableSessionPoolBuilder.java
@@ -281,6 +281,18 @@ public class TableSessionPoolBuilder extends 
AbstractSessionPoolBuilder {
     return this;
   }
 
+  /**
+   * Sets the SSL protocol for secure connections.
+   *
+   * @param sslProtocol the SSL protocol.
+   * @return the current {@link TableSessionPoolBuilder} instance.
+   * @defaultValue TLS
+   */
+  public TableSessionPoolBuilder sslProtocol(String sslProtocol) {
+    this.sslProtocol = sslProtocol;
+    return this;
+  }
+
   /**
    * Builds and returns a configured {@link ITableSessionPool} instance.
    *
diff --git 
a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/iot/client/SyncIoTConsensusServiceClient.java
 
b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/iot/client/SyncIoTConsensusServiceClient.java
index 43b2f60d89f..3f3eb2d358e 100644
--- 
a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/iot/client/SyncIoTConsensusServiceClient.java
+++ 
b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/iot/client/SyncIoTConsensusServiceClient.java
@@ -61,7 +61,8 @@ public class SyncIoTConsensusServiceClient extends 
IoTConsensusIService.Client
                         commonConfig.getTrustStorePath(),
                         commonConfig.getTrustStorePwd(),
                         commonConfig.getKeyStorePath(),
-                        commonConfig.getKeyStorePwd())
+                        commonConfig.getKeyStorePwd(),
+                        commonConfig.getSslProtocol())
                     : DeepCopyRpcTransportFactory.INSTANCE.getTransport(
                         new TSocket(
                             TConfigurationConst.defaultTConfiguration,
diff --git 
a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/utils/NoHostnameVerificationTrustManager.java
 
b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/utils/NoHostnameVerificationTrustManager.java
deleted file mode 100644
index fb5c9085488..00000000000
--- 
a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/utils/NoHostnameVerificationTrustManager.java
+++ /dev/null
@@ -1,88 +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.iotdb.consensus.ratis.utils;
-
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.X509ExtendedTrustManager;
-import javax.net.ssl.X509TrustManager;
-
-import java.net.Socket;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-
-public class NoHostnameVerificationTrustManager extends 
X509ExtendedTrustManager {
-
-  private final X509TrustManager delegate;
-
-  public NoHostnameVerificationTrustManager(X509TrustManager delegate) {
-    this.delegate = delegate;
-  }
-
-  @Override
-  public X509Certificate[] getAcceptedIssuers() {
-    return delegate.getAcceptedIssuers();
-  }
-
-  @Override
-  public void checkClientTrusted(X509Certificate[] chain, String authType)
-      throws CertificateException {
-    delegate.checkClientTrusted(chain, authType);
-  }
-
-  @Override
-  public void checkServerTrusted(X509Certificate[] chain, String authType)
-      throws CertificateException {
-    delegate.checkServerTrusted(chain, authType);
-  }
-
-  @Override
-  public void checkClientTrusted(X509Certificate[] chain, String authType, 
Socket socket)
-      throws CertificateException {
-    if (delegate instanceof X509ExtendedTrustManager) {
-      ((X509ExtendedTrustManager) delegate).checkClientTrusted(chain, 
authType, socket);
-    } else {
-      delegate.checkClientTrusted(chain, authType);
-    }
-  }
-
-  @Override
-  public void checkServerTrusted(X509Certificate[] chain, String authType, 
Socket socket)
-      throws CertificateException {
-    // Skip hostname check by calling base method
-    delegate.checkServerTrusted(chain, authType);
-  }
-
-  @Override
-  public void checkClientTrusted(X509Certificate[] chain, String authType, 
SSLEngine engine)
-      throws CertificateException {
-    if (delegate instanceof X509ExtendedTrustManager) {
-      ((X509ExtendedTrustManager) delegate).checkClientTrusted(chain, 
authType, engine);
-    } else {
-      delegate.checkClientTrusted(chain, authType);
-    }
-  }
-
-  @Override
-  public void checkServerTrusted(X509Certificate[] chain, String authType, 
SSLEngine engine)
-      throws CertificateException {
-    // Skip hostname check by calling base method
-    delegate.checkServerTrusted(chain, authType);
-  }
-}
diff --git 
a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/utils/Utils.java
 
b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/utils/Utils.java
index 2c24ff12b6d..442ac484064 100644
--- 
a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/utils/Utils.java
+++ 
b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/utils/Utils.java
@@ -29,6 +29,7 @@ import org.apache.iotdb.consensus.common.Peer;
 import org.apache.iotdb.consensus.config.RatisConfig;
 import org.apache.iotdb.consensus.i18n.ConsensusMessages;
 import org.apache.iotdb.rpc.AutoScalingBufferWriteTransport;
+import org.apache.iotdb.rpc.RpcSslUtils;
 
 import org.apache.ratis.client.RaftClientConfigKeys;
 import org.apache.ratis.conf.Parameters;
@@ -53,19 +54,12 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.net.ssl.KeyManager;
-import javax.net.ssl.KeyManagerFactory;
 import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.X509TrustManager;
 
 import java.io.File;
 import java.io.FileNotFoundException;
-import java.io.InputStream;
 import java.nio.ByteBuffer;
 import java.nio.file.AccessDeniedException;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.security.KeyStore;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
@@ -371,31 +365,10 @@ public class Utils {
       String keyStorePassword = config.getGrpc().getSslKeyStorePassword();
       String trustStorePath = config.getGrpc().getSslTrustStorePath();
       String trustStorePassword = config.getGrpc().getSslTrustStorePassword();
-      try (InputStream keyStoreStream = 
Files.newInputStream(Paths.get(keyStorePath));
-          InputStream trustStoreStream = 
Files.newInputStream(Paths.get(trustStorePath))) {
-        // === 1) create KeyManager ===
-        KeyStore keyStore = KeyStore.getInstance("JKS");
-        keyStore.load(keyStoreStream, keyStorePassword.toCharArray());
-
-        KeyManagerFactory kmf =
-            
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
-        kmf.init(keyStore, keyStorePassword.toCharArray());
-        KeyManager keyManager = kmf.getKeyManagers()[0];
-
-        // === 2) create TrustManager ===
-        KeyStore trustStore = KeyStore.getInstance("JKS");
-        trustStore.load(trustStoreStream, trustStorePassword.toCharArray());
-
-        TrustManagerFactory tmf =
-            
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
-        tmf.init(trustStore);
-        TrustManager originalTrustManager = tmf.getTrustManagers()[0];
-
-        // The self-signed certification may not set Subject Alternative Name 
(SAN)
-        // Thrift with ssl didn't check it, but Grpc did.
-        // Wrap to disable the verification
+      try {
+        KeyManager keyManager = RpcSslUtils.createKeyManagers(keyStorePath, 
keyStorePassword)[0];
         TrustManager trustManager =
-            new NoHostnameVerificationTrustManager((X509TrustManager) 
originalTrustManager);
+            RpcSslUtils.createTrustManagers(trustStorePath, 
trustStorePassword)[0];
         GrpcConfigKeys.TLS.setConf(parameters, new GrpcTlsConfig(keyManager, 
trustManager, true));
       } catch (AccessDeniedException e) {
         LOGGER.error(ConsensusMessages.FAILED_TO_LOAD_KEYSTORE);
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/rest/IoTDBRestServiceConfig.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/rest/IoTDBRestServiceConfig.java
index f6b7848d8ac..b7af9dcb201 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/rest/IoTDBRestServiceConfig.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/rest/IoTDBRestServiceConfig.java
@@ -45,6 +45,9 @@ public class IoTDBRestServiceConfig {
   /** ssl trust Store password. */
   private String trustStorePwd = "";
 
+  /** SSL protocol. */
+  private String sslProtocol = "";
+
   /** ssl timeout. */
   private int idleTimeoutInSeconds = 50000;
 
@@ -78,6 +81,14 @@ public class IoTDBRestServiceConfig {
     this.trustStorePwd = trustStorePwd;
   }
 
+  public String getSslProtocol() {
+    return sslProtocol;
+  }
+
+  public void setSslProtocol(String sslProtocol) {
+    this.sslProtocol = sslProtocol;
+  }
+
   public int getIdleTimeoutInSeconds() {
     return idleTimeoutInSeconds;
   }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/rest/IoTDBRestServiceDescriptor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/rest/IoTDBRestServiceDescriptor.java
index 2e4ed0c28a6..807ef3054e7 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/rest/IoTDBRestServiceDescriptor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/rest/IoTDBRestServiceDescriptor.java
@@ -23,6 +23,7 @@ import org.apache.iotdb.commons.conf.IoTDBConstant;
 import org.apache.iotdb.commons.conf.TrimProperties;
 import org.apache.iotdb.db.conf.IoTDBConfig;
 import org.apache.iotdb.db.i18n.DataNodeMiscMessages;
+import org.apache.iotdb.rpc.RpcSslUtils;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -108,6 +109,9 @@ public class IoTDBRestServiceDescriptor {
     conf.setTrustStorePath(
         trimProperties.getProperty("trust_store_path", 
conf.getTrustStorePath()));
     conf.setTrustStorePwd(trimProperties.getProperty("trust_store_pwd", 
conf.getTrustStorePwd()));
+    conf.setSslProtocol(
+        RpcSslUtils.normalizeProtocol(
+            trimProperties.getProperty("ssl_protocol", 
conf.getSslProtocol())));
     conf.setIdleTimeoutInSeconds(
         Integer.parseInt(
             trimProperties.getProperty(
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/ConfigNodeClient.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/ConfigNodeClient.java
index 12153a19eed..ec55111a200 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/ConfigNodeClient.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/ConfigNodeClient.java
@@ -283,7 +283,8 @@ public class ConfigNodeClient implements 
IConfigNodeRPCService.Iface, ThriftClie
                 commonConfig.getTrustStorePath(),
                 commonConfig.getTrustStorePwd(),
                 commonConfig.getKeyStorePath(),
-                commonConfig.getKeyStorePwd())
+                commonConfig.getKeyStorePwd(),
+                commonConfig.getSslProtocol())
             : DeepCopyRpcTransportFactory.INSTANCE.getTransport(
                 // As there is a try-catch already, we do not need to use 
TSocket.wrap
                 endpoint.getIp(), endpoint.getPort(), timeoutMs);
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/an/AINodeClient.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/an/AINodeClient.java
index 46af33b3172..6efb5a8c021 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/an/AINodeClient.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/an/AINodeClient.java
@@ -222,7 +222,8 @@ public class AINodeClient implements 
IAINodeRPCService.Iface, AutoCloseable, Thr
                 COMMON_CONFIG.getTrustStorePath(),
                 COMMON_CONFIG.getTrustStorePwd(),
                 COMMON_CONFIG.getKeyStorePath(),
-                COMMON_CONFIG.getKeyStorePwd())
+                COMMON_CONFIG.getKeyStorePwd(),
+                COMMON_CONFIG.getSslProtocol())
             : DeepCopyRpcTransportFactory.INSTANCE.getTransport(
                 // As there is a try-catch already, we do not need to use 
TSocket.wrap
                 endpoint.getIp(), endpoint.getPort(), timeoutMs);
diff --git 
a/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template
 
b/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template
index 2bd65bb3f98..56f64fb8f12 100644
--- 
a/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template
+++ 
b/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template
@@ -474,6 +474,14 @@ trust_store_path=
 # Datatype: String
 trust_store_pwd=
 
+# SSL protocol used by server-side SSL services.
+# The protocol is passed to the current JSSE provider, such as TLS, TLSv1.2,
+# TLSv1.3, or another provider-specific SSL protocol name.
+# effectiveMode: restart
+# Datatype: String
+# Privilege: SECURITY
+ssl_protocol=TLS
+
 ####################
 ### Connection Configuration
 ####################
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncAINodeClient.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncAINodeClient.java
index 054b6446099..63600710704 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncAINodeClient.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncAINodeClient.java
@@ -63,7 +63,8 @@ public class SyncAINodeClient extends IAINodeRPCService.Client
                         COMMON_CONFIG.getTrustStorePath(),
                         COMMON_CONFIG.getTrustStorePwd(),
                         COMMON_CONFIG.getKeyStorePath(),
-                        COMMON_CONFIG.getKeyStorePwd())
+                        COMMON_CONFIG.getKeyStorePwd(),
+                        COMMON_CONFIG.getSslProtocol())
                     : DeepCopyRpcTransportFactory.INSTANCE.getTransport(
                         new TSocket(
                             TConfigurationConst.defaultTConfiguration,
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncConfigNodeIServiceClient.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncConfigNodeIServiceClient.java
index ced2c92b4a0..323e00bace1 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncConfigNodeIServiceClient.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncConfigNodeIServiceClient.java
@@ -63,7 +63,8 @@ public class SyncConfigNodeIServiceClient extends 
IConfigNodeRPCService.Client
                         commonConfig.getTrustStorePath(),
                         commonConfig.getTrustStorePwd(),
                         commonConfig.getKeyStorePath(),
-                        commonConfig.getKeyStorePwd())
+                        commonConfig.getKeyStorePwd(),
+                        commonConfig.getSslProtocol())
                     : DeepCopyRpcTransportFactory.INSTANCE.getTransport(
                         new TSocket(
                             TConfigurationConst.defaultTConfiguration,
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncDataNodeInternalServiceClient.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncDataNodeInternalServiceClient.java
index 854b4a4aa18..3f51cfa5d3e 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncDataNodeInternalServiceClient.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncDataNodeInternalServiceClient.java
@@ -64,7 +64,8 @@ public class SyncDataNodeInternalServiceClient extends 
IDataNodeRPCService.Clien
                         commonConfig.getTrustStorePath(),
                         commonConfig.getTrustStorePwd(),
                         commonConfig.getKeyStorePath(),
-                        commonConfig.getKeyStorePwd())
+                        commonConfig.getKeyStorePwd(),
+                        commonConfig.getSslProtocol())
                     : DeepCopyRpcTransportFactory.INSTANCE.getTransport(
                         new TSocket(
                             TConfigurationConst.defaultTConfiguration,
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncDataNodeMPPDataExchangeServiceClient.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncDataNodeMPPDataExchangeServiceClient.java
index 4dcde11bfac..b4393bfd4ee 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncDataNodeMPPDataExchangeServiceClient.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncDataNodeMPPDataExchangeServiceClient.java
@@ -63,7 +63,8 @@ public class SyncDataNodeMPPDataExchangeServiceClient extends 
MPPDataExchangeSer
                         commonConfig.getTrustStorePath(),
                         commonConfig.getTrustStorePwd(),
                         commonConfig.getKeyStorePath(),
-                        commonConfig.getKeyStorePwd())
+                        commonConfig.getKeyStorePwd(),
+                        commonConfig.getSslProtocol())
                     : DeepCopyRpcTransportFactory.INSTANCE.getTransport(
                         new TSocket(
                             TConfigurationConst.defaultTConfiguration,
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncIoTConsensusV2ServiceClient.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncIoTConsensusV2ServiceClient.java
index 3073434c921..0b744242775 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncIoTConsensusV2ServiceClient.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/sync/SyncIoTConsensusV2ServiceClient.java
@@ -63,7 +63,8 @@ public class SyncIoTConsensusV2ServiceClient extends 
IoTConsensusV2IService.Clie
                         commonConfig.getTrustStorePath(),
                         commonConfig.getTrustStorePwd(),
                         commonConfig.getKeyStorePath(),
-                        commonConfig.getKeyStorePwd())
+                        commonConfig.getKeyStorePwd(),
+                        commonConfig.getSslProtocol())
                     : DeepCopyRpcTransportFactory.INSTANCE.getTransport(
                         new TSocket(
                             TConfigurationConst.defaultTConfiguration,
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java
index 6ec3478109e..25315ba4c2f 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java
@@ -499,6 +499,9 @@ public class CommonConfig {
   /** ssl trust Store password. */
   private String trustStorePwd = "";
 
+  /** SSL protocol. */
+  private String sslProtocol = "TLS";
+
   private String userEncryptTokenHint = "not set yet";
 
   private boolean enforceStrongPassword = false;
@@ -3009,6 +3012,14 @@ public class CommonConfig {
     this.trustStorePwd = trustStorePwd;
   }
 
+  public String getSslProtocol() {
+    return sslProtocol;
+  }
+
+  public void setSslProtocol(String sslProtocol) {
+    this.sslProtocol = sslProtocol;
+  }
+
   public boolean isEnforceStrongPassword() {
     return enforceStrongPassword;
   }
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonDescriptor.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonDescriptor.java
index 3242639c7e1..9c039cf25c2 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonDescriptor.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonDescriptor.java
@@ -24,6 +24,7 @@ import org.apache.iotdb.commons.pipe.config.PipeDescriptor;
 import org.apache.iotdb.commons.utils.CommonDateTimeUtils;
 import org.apache.iotdb.confignode.rpc.thrift.TAuditConfig;
 import org.apache.iotdb.confignode.rpc.thrift.TGlobalConfig;
+import org.apache.iotdb.rpc.RpcSslUtils;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -658,5 +659,13 @@ public class CommonDescriptor {
     config.setTrustStorePath(
         properties.getProperty("trust_store_path", 
config.getTrustStorePath()));
     config.setTrustStorePwd(properties.getProperty("trust_store_pwd", 
config.getTrustStorePwd()));
+    config.setSslProtocol(
+        RpcSslUtils.normalizeProtocol(
+            properties.getProperty("ssl_protocol", config.getSslProtocol())));
+    configureRpcSsl();
+  }
+
+  public void configureRpcSsl() {
+    RpcSslUtils.configure(config.getSslProtocol());
   }
 }
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/service/AbstractThriftServiceThread.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/service/AbstractThriftServiceThread.java
index 84361727a32..cd2716108ce 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/service/AbstractThriftServiceThread.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/service/AbstractThriftServiceThread.java
@@ -24,6 +24,7 @@ import 
org.apache.iotdb.commons.concurrent.threadpool.WrappedThreadPoolExecutor;
 import org.apache.iotdb.commons.conf.IoTDBConstant;
 import org.apache.iotdb.commons.exception.runtime.RPCServiceException;
 import org.apache.iotdb.commons.i18n.ServiceMessages;
+import org.apache.iotdb.rpc.RpcSslUtils;
 
 import org.apache.thrift.TBaseAsyncProcessor;
 import org.apache.thrift.TProcessor;
@@ -45,13 +46,7 @@ import org.apache.thrift.transport.TTransportFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.net.InetSocketAddress;
-import java.nio.file.AccessDeniedException;
-import java.security.KeyStore;
-import java.security.cert.X509Certificate;
-import java.util.Enumeration;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.TimeUnit;
@@ -184,13 +179,13 @@ public abstract class AbstractThriftServiceThread extends 
Thread {
     this.serviceName = serviceName;
 
     try {
-      validateCertificate(keyStorePath, keyStorePwd);
+      RpcSslUtils.validateKeyStore(keyStorePath, keyStorePwd);
       TSSLTransportFactory.TSSLTransportParameters params =
-          new TSSLTransportFactory.TSSLTransportParameters();
-      params.setKeyStore(keyStorePath, keyStorePwd);
+          RpcSslUtils.createTSSLTransportParameters();
+      RpcSslUtils.setKeyStore(params, keyStorePath, keyStorePwd);
       if (trustStorePath != null && !trustStorePath.isEmpty()) {
-        validateCertificate(trustStorePath, trustStorePwd);
-        params.setTrustStore(trustStorePath, trustStorePwd);
+        RpcSslUtils.validateTrustStore(trustStorePath, trustStorePwd);
+        RpcSslUtils.setTrustStore(params, trustStorePath, trustStorePwd);
         params.requireClientAuth(true);
       }
       InetSocketAddress socketAddress = new InetSocketAddress(bindAddress, 
port);
@@ -206,41 +201,6 @@ public abstract class AbstractThriftServiceThread extends 
Thread {
     }
   }
 
-  private static void validateCertificate(String keyStorePath, String 
keystorePassword)
-      throws TTransportException {
-    try {
-      KeyStore keystore = KeyStore.getInstance("JKS");
-      try (FileInputStream fis = new FileInputStream(keyStorePath)) {
-        keystore.load(fis, keystorePassword.toCharArray());
-      }
-
-      Enumeration<String> aliases = keystore.aliases();
-      while (aliases.hasMoreElements()) {
-        String currentAlias = aliases.nextElement();
-        checkCertificate(keystore, currentAlias);
-      }
-    } catch (AccessDeniedException e) {
-      throw new 
TTransportException(ServiceMessages.FAILED_TO_LOAD_KEYSTORE_OR_TRUSTSTORE);
-    } catch (FileNotFoundException e) {
-      throw new 
TTransportException(ServiceMessages.KEYSTORE_OR_TRUSTSTORE_NOT_FOUND);
-    } catch (Exception e) {
-      throw new TTransportException(e);
-    }
-  }
-
-  private static void checkCertificate(KeyStore keystore, String alias) throws 
Exception {
-    if (!keystore.containsAlias(alias)) {
-      return;
-    }
-
-    X509Certificate cert = (X509Certificate) keystore.getCertificate(alias);
-    if (cert == null) {
-      return;
-    }
-
-    cert.checkValidity();
-  }
-
   @SuppressWarnings("squid:S107")
   protected AbstractThriftServiceThread(
       TProcessor processor,
diff --git a/pom.xml b/pom.xml
index c577243cb0a..3f3b235f19a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -119,7 +119,7 @@
         <pax-jdbc-common.version>1.5.6</pax-jdbc-common.version>
         <powermock.version>2.0.9</powermock.version>
         <ratis-thirdparty-misc.version>1.0.11</ratis-thirdparty-misc.version>
-        <ratis.version>3.2.2</ratis.version>
+        <ratis.version>3.3.0-adac7ef-SNAPSHOT</ratis.version>
         <reactive-streams.version>1.0.4</reactive-streams.version>
         <reactor-netty.version>1.2.9</reactor-netty.version>
         <reactor.version>3.7.9</reactor.version>
@@ -331,6 +331,16 @@
                 <groupId>org.apache.ratis</groupId>
                 <artifactId>ratis-common</artifactId>
                 <version>${ratis.version}</version>
+                <exclusions>
+                    <exclusion>
+                        <groupId>io.opentelemetry</groupId>
+                        <artifactId>opentelemetry-api</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>io.opentelemetry</groupId>
+                        <artifactId>opentelemetry-context</artifactId>
+                    </exclusion>
+                </exclusions>
             </dependency>
             <dependency>
                 <groupId>org.apache.ratis</groupId>

Reply via email to