0

My android app needs to login and scrap the data under this domain name (*.nkust.edu.tw).

The problem is that I found that the certificate installation of the server is not complete (SSL Checker result). Since I am not the administrator of the server, I would like to ask if there is any way reconstruct the certification chain programmatically?

I've referenced Add Server Certificate Information to Trust Manager Android Programmatically but it seems slightly different from the problem I have.

I'm now using kotlin with ktor over http, which I know it's unsafe for passing login info, and when it comes to downloading some file like pdf, it'll throw "sun.security.provider.certpath.SunCertPathBuilderException".

Certifications (root, server, uca) can be obtained from the following URL: https://ssl2.twca.com.tw/NCWebSSL/search.htm?dns=*.nkust.edu.tw

1 Answers1

0

Okay, so I use ssl pinning: https://ktor.io/docs/client-ssl.html

not sure if it's the right way to do, but it works.

class SslSettings(val context: Context) {
    fun getKeyStore(): KeyStore {
        // read file from res folder (keyStoreFile.jks)
        // generate .jks from .pem using keytool
        val keyStoreFile = context.resources.openRawResource(R.raw.keyStoreFile)
        val keyStorePassword = "Custom_Password".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
    }
}

then

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