Skip to content
Client Plugin

Ktor Client의 SSL

코드 예제: client-ssl-config

Ktor 클라이언트에서 SSL을 설정하려면, 클라이언트에서 사용하는 엔진 설정을 사용자 정의해야 합니다. 이 주제에서는 JVMAndroid를 대상으로 하는 엔진에 SSL 인증서를 추가하는 방법을 살펴봅니다.

Ktor API를 사용하여 자가 서명 인증서를 생성하는 방법을 알아보려면 자가 서명 인증서 생성을 참조하세요.

SSL 설정 로드

이 주제에서 Ktor 클라이언트는 서버용으로 생성된 기존 KeyStore 파일(keystore.jks)에서 로드된 인증서를 사용합니다. 엔진마다 SSL을 설정하는 데 서로 다른 JSSE API(예: Apache의 경우 SSLContext, Jetty의 경우 TrustManager)를 사용하므로, 해당 SSL 설정을 가져올 수 있는 기능이 필요합니다. 아래 코드 스니펫은 기존 KeyStore 파일(keystore.jks)에서 인증서를 로드하고 SSL 설정을 로드하기 위한 함수를 제공하는 SslSettings 객체를 생성합니다.

kotlin
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
    }
}

Ktor에서 SSL 설정

이 섹션에서는 각 엔진별로 SSL을 설정하는 방법을 살펴보겠습니다. 전체 예제는 여기에서 확인할 수 있습니다: client-ssl-config.

JVM

Apache

Apache에 SSL을 활성화하려면 SSLContext를 전달해야 합니다.

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

Java

Java 클라이언트의 경우, config 블록 내부의 sslContext 함수에 SSLContext를 전달합니다.

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

Jetty

Jetty의 경우, SslContextFactory 인스턴스를 생성하고 SSLContext를 전달해야 합니다.

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

JVM 및 Android

Android용 모든 엔진은 네트워크 보안 구성을 사용합니다.

CIO

CIO 엔진을 사용하면 https 블록 내에서 HTTPS 설정을 구성할 수 있습니다. 이 블록 내부에서는 TLSConfigBuilder가 제공하는 TLS 파라미터에 접근할 수 있습니다. 이 예제에서는 인증서를 설정하기 위해 TrustManager 인스턴스가 사용됩니다.

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

sockets-client-tls 예제는 모든 인증서를 신뢰하는 방법을 보여줍니다. 이 방식은 개발 목적으로만 사용해야 합니다.

Android

Android 엔진은 sslManager 프로퍼티를 사용하여 SSL 설정을 구성합니다. 이 프로퍼티는 SSLSocketFactory를 전달할 수 있게 해주는 HttpsURLConnection을 파라미터로 받습니다.

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

OkHttp

OkHttp가 SSL을 사용하도록 설정하려면 sslSocketFactory 함수에 SSLSocketFactoryX509TrustManager를 전달해야 합니다.

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

Darwin

Darwin 엔진에 대해 신뢰할 수 있는 인증서를 설정하려면 CertificatePinner를 사용하세요.