Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting up SSL on ktor server using Android Keystore

I an trying to set up SSL on a Ktor Server on Android. The certificates are loaded at runtime, so i am using a AndroidKeyStore to store them. However, ktor is unable to initialize. It seems like AndroidKeyStore is implented to throw an exception whenever a KeyStorePassword is provided. So to add the key to AndroidKeyStore, i have to provide a null password like so keystore.setKeyEntry(alias, keyPair.private, null, arrayOf(certificate))

But when i then pass the keystore to ktor, i get a NullPointerException, because ktor tries to interact with the password when it is null. My ktor setup looks like

embeddedServer(Netty, applicationEngineEnvironment {
  sslConnector(
    keyStore = keyStore,
    keyAlias = alias,
    keyStorePassword = { charArrayOf() },
    privateKeyPassword = { charArrayOf() }
    )
})

I have tried both versions 2.0.3 and 1.6,8 of Ktor, and am using Android sdk version 28

So my queston is - is there any way to use AndroidKeyStore with ktor, and if not, what would be the best alternative with regards to security?

like image 839
Ous Avatar asked Dec 21 '25 17:12

Ous


1 Answers

The problem is not a keystore password or a private key password, but Netty implementation. It tries to create a ssl context with a new KeyStore, self created, with copied keys/certsChain from the keystore provided in sslConnector. In case your keystore is AndroidKeyStore type, you cannot extract keys outside of the keystore. Sure you can get a KeyPair object with Public/PrivateKey objects, but they just have ids to identify the encrypted keys inside AndroidKeyStore, not the real keys exponents.

So when Netty tries to get the real key from AndroidKeyStore (like by getEncoded function), it gets null and crashes during initialization.

https://developer.android.com/privacy-and-security/keystore#ExtractionPrevention

Solution proposed here https://youtrack.jetbrains.com/issue/KTOR-4730, pointed by Aleksei, replaces "BC" provider, to the Bouncy Castle provider. I think it disables following workaround: https://android.googlesource.com/platform/frameworks/base/+/refs/heads/main/keystore/java/android/security/keystore2/AndroidKeyStoreBCWorkaroundProvider.java that is why it works, but it reduces security anyway.

like image 90
user1770426 Avatar answered Dec 23 '25 06:12

user1770426