Ktor 2.3.1 Help


To configure SSL in the Ktor client, you need to customize the configuration of an engine used by your client. In this topic, we'll show you how to add an SSL certificate for engines that target JVM and Android.

Load SSL settings

In this topic, the Ktor client will be using a certificate loaded from the existing KeyStore file (keystore.jks) generated for the server. Given that different engines use different JSSE API to configure SSL (for example, SSLContext for Apache or TrustManager for Jetty), we need to have the capability to obtain corresponding SSL configurations. The code snippet below creates the SslSettings object that loads a certificate from the existing KeyStore file (keystore.jks) and provides functions for loading SSL configurations:

object SslSettings { fun getKeyStore(): KeyStore { val keyStoreFile = FileInputStream("keystore.jks") val keyStorePassword = "foobar".toCharArray() val keyStore: KeyStore = KeyStore.getInstance(KeyStore.getDefaultType()) keyStore.load(keyStoreFile, keyStorePassword) return keyStore } fun getTrustManagerFactory(): TrustManagerFactory? { val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()) trustManagerFactory.init(getKeyStore()) return trustManagerFactory } fun getSslContext(): SSLContext? { val sslContext = SSLContext.getInstance("TLS") sslContext.init(null, getTrustManagerFactory()?.trustManagers, null) return sslContext } fun getTrustManager(): X509TrustManager { return getTrustManagerFactory()?.trustManagers?.first { it is X509TrustManager } as X509TrustManager } }

Configure SSL in Ktor

In this section, we'll see how to configure SSL for different engines. You can find the full example here: client-ssl-config.



To enable SSL for Apache, you need to pass SSLContext:

val apacheClient = HttpClient(Apache5) { engine { sslContext = SslSettings.getSslContext() } }


For the Java client, pass SSLContext to the sslContext function inside the config block:

val javaClient = HttpClient(Java) { engine { config { sslContext(SslSettings.getSslContext()) } } }


For Jetty, you need to create an instance of SslContextFactory and pass SSLContext:

val jettyClient = HttpClient(Jetty) { engine { sslContextFactory = SslContextFactory.Client().apply { sslContext = SslSettings.getSslContext() } } }

JVM and Android


The CIO engine allows you to configure HTTPS settings inside the https block. Inside this block, you can access TLS parameters provided by TLSConfigBuilder. In our example, a TrustManager instance is used to configure a certificate:

val cioClient = HttpClient(CIO) { engine { https { trustManager = SslSettings.getTrustManager() } } }


The Android engine uses the sslManager property to configure SSL settings. This property accepts HttpsURLConnection as a parameter that allows you to pass SSLSocketFactory:

val androidClient = HttpClient(Android) { engine { sslManager = { httpsURLConnection -> httpsURLConnection.sslSocketFactory = SslSettings.getSslContext()?.socketFactory } } }


To configure OkHttp for using SSL, you need to pass SSLSocketFactory and X509TrustManager to the sslSocketFactory function:

val okHttpClient = HttpClient(OkHttp) { engine { config { sslSocketFactory(SslSettings.getSslContext()!!.socketFactory, SslSettings.getTrustManager()) } } }


To configure trusted certificates for the Darwin engine, use CertificatePinner.

Last modified: 21 July 2022