简体   繁体   中英

GRPC Okhttp android client channel with self signed ssl certificate

I have a grpc-js server using self signed ssl certificates.

var credentials = grpc.ServerCredentials.createSsl(
    fs.readFileSync('./node/grpc/ssl/ca.crt'), 
    [{
        cert_chain: fs.readFileSync('./node/grpc/ssl/server.crt'),
        private_key: fs.readFileSync('./node/grpc/ssl/server.key')
    }], 
    true
);

I then tested this setup with a grpc-js client with the following credential setup and this works.

var credentials = grpc.credentials.createSsl(
    fs.readFileSync('./node/grpc/ssl/ca.crt'),
    fs.readFileSync('./node/grpc/ssl/client.key'),
    fs.readFileSync('./node/grpc/ssl/client.crt')
);

I want to replicate this in Android using OkHttpChannelBuilder but it is a bit more complicated. This is what I have so far.

private val mChannel : ManagedChannel
init {
    /**
     * Server certificate to make it trusted.
     */
    val serverCrtFile = applicationContext.resources.openRawResource(R.raw.server)
    val serverCertificate: X509Certificate =
        CertificateFactory.getInstance("X.509").generateCertificate(serverCrtFile) as X509Certificate

    val caKeyStore: KeyStore = KeyStore.getInstance(KeyStore.getDefaultType()).apply {
        load(null, null)
        setCertificateEntry("server", serverCertificate)
    }

    val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()).apply {
        init(caKeyStore)
    }

    val sslContext = SSLContext.getInstance("TLS").apply {
        init(null, trustManagerFactory.trustManagers, null)
    }

    mChannel = OkHttpChannelBuilder
        .forAddress(BuildConfig.GRPC_HOST_ADDRESS, BuildConfig.GRPC_HOST_PORT)
        .sslSocketFactory(sslContext.socketFactory)
        .keepAliveTime(10, TimeUnit.SECONDS)
        .useTransportSecurity()
        .keepAliveWithoutCalls(true)
        .build()
}

Everything worked before implementing ssl (so using plaintext() on the channel builder).

The error I get now is io.grpc.StatusRuntimeException: UNAVAILABLE: End of stream or IOException . Can someone please tell me if I am doing something wrong and how I can get a successful connection like between the js server and client.

Looks like the SSL handshake failed on the server side so it will be helpful to get server side detailed logs to see what went wrong.

One possibility is using KeyStore.getInstance . Can you try using "PKCS12" ?

 KeyStore.getInstance("PKCS12")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM