I am using the Ktor in my native application,
- In which I will be receiving the Public key from the login API.
- This public key I will be saving in a preference at init
- Now I need to use this public key as part of Ktor client so that on each network call I will be validating the Key which will prevent Man in middle Attack as part of security
Hence I need to implement the SSL pinning as part of Ktor Client , Guide me on how to implement in native Android Application
My Ktor client look as below
val ktorHttpClient = HttpClient(Android) {
expectSuccess = true
install(ContentNegotiation) {
json(Json {
prettyPrint = true
isLenient = true
ignoreUnknownKeys = true
explicitNulls = false
})
}
}
In this I need to configure the SSL pinning via public key
SSL Manager Impl with engine in ktor, but the engine block is not executed confirmed with the log
val pin = "sha256/afwiKY3RxoMmLkuRW1l7QsPZTJPwDS2pdDROQjXw8ig="
val PINNED_HOST_NAME = "qual.abc.com"
engine {
sslManager = { httpsURLConnection ->
httpsURLConnection.hostnameVerifier = object : HostnameVerifier {
override fun verify(hostname: String?, session: SSLSession?): Boolean {
// Check if the hostname matches the expected domain
if (!hostname.equals(PINNED_HOST_NAME, ignoreCase = true)) return false
// Extract the server's certificate chain
val certificates = session?.peerCertificates ?: return false
// Get the public key from the first certificate in the chain
val serverPublicKey = certificates[0].publicKey.encoded
// Convert the server's public key byte array to a hexadecimal string
val serverPublicKeyHex = Base64.encodeToString(serverPublicKey, Base64.NO_WRAP).toString()
Timber.tag("SSL pin").d("${pin.contentEquals(serverPublicKeyHex)}")
// Compare the server's public key with the pinned public key
return pin.contentEquals(serverPublicKeyHex)
}
}
// httpsURLConnection.sslSocketFactory = sslFactory.sslSocketFactory
}
}
9