Skip to content

Can't make it work on Android #8

@RobbWatershed

Description

@RobbWatershed

I'm trying to use the library to work with OkHttp but I can't make it work at all...

Environment : Android (API 30)

Scenario 1 : Using both impersonator's OkHttp and bctls modules

Code

val api = ImpersonatorFactory.macChrome()
val factory = OkHttpClientFactory.create(api)
return factory.newHttpClient()

Result

java.lang.NoClassDefFoundError: okhttp3.internal.platform.Platform
	at okhttp3.internal.tls.CertificateChainCleaner$Companion.get(CertificateChainCleaner.kt:42)
	at okhttp3.OkHttpClient$Builder.sslSocketFactory(OkHttpClient.kt:811)
	at okhttp3.DefaultHttpClientFactory.newHttpClientInternal(DefaultHttpClientFactory.java:64)
	at okhttp3.DefaultHttpClientFactory.newHttpClient(DefaultHttpClientFactory.java:55)
	at okhttp3.DefaultHttpClientFactory.newHttpClient(DefaultHttpClientFactory.java:48)
	at okhttp3.DefaultHttpClientFactory.newHttpClient(DefaultHttpClientFactory.java:36)
	at ...
Caused by: java.lang.ExceptionInInitializerError
	at okhttp3.OkHttpClient.<init>(OkHttpClient.kt:237)
	at okhttp3.OkHttpClient.<init>(OkHttpClient.kt:222)
	at coil3.network.okhttp.OkHttpNetworkFetcher.OkHttpNetworkFetcherFactory$lambda$0(OkHttpNetworkFetcher.kt:16)
	at coil3.network.okhttp.OkHttpNetworkFetcher$$ExternalSyntheticLambda2.invoke(D8$$SyntheticClass:0)
	at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:86)
	at coil3.network.NetworkFetcher.executeNetworkRequest(NetworkFetcher.kt:201)
	at coil3.network.NetworkFetcher.fetch(NetworkFetcher.kt:74)
	at coil3.intercept.EngineInterceptor.fetch(EngineInterceptor.kt:169)
	at coil3.intercept.EngineInterceptor.execute(EngineInterceptor.kt:126)
	at coil3.intercept.EngineInterceptor.access$execute(EngineInterceptor.kt:43)
	at coil3.intercept.EngineInterceptor$intercept$2.invokeSuspend(EngineInterceptor.kt:77)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:34)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100)
	at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:124)
	at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:89)
	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:586)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:820)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:717)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:704)
Caused by: java.lang.UnsupportedOperationException: Android platform does not support okhttp3.internal.platform.Platform
	at okhttp3.internal.platform.Platform$Companion.findPlatform(Platform.kt:219)
	at okhttp3.internal.platform.Platform$Companion.access$findPlatform(Platform.kt:176)
	at okhttp3.internal.platform.Platform.<clinit>(Platform.kt:177)
	at okhttp3.OkHttpClient.<init>(OkHttpClient.kt:237) 
	at okhttp3.OkHttpClient.<init>(OkHttpClient.kt:222) 
	at coil3.network.okhttp.OkHttpNetworkFetcher.OkHttpNetworkFetcherFactory$lambda$0(OkHttpNetworkFetcher.kt:16) 
	at coil3.network.okhttp.OkHttpNetworkFetcher$$ExternalSyntheticLambda2.invoke(D8$$SyntheticClass:0) 
	at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:86) 
	at coil3.network.NetworkFetcher.executeNetworkRequest(NetworkFetcher.kt:201) 
	at coil3.network.NetworkFetcher.fetch(NetworkFetcher.kt:74) 
	at coil3.intercept.EngineInterceptor.fetch(EngineInterceptor.kt:169) 
	at coil3.intercept.EngineInterceptor.execute(EngineInterceptor.kt:126) 
	at coil3.intercept.EngineInterceptor.access$execute(EngineInterceptor.kt:43) 
	at coil3.intercept.EngineInterceptor$intercept$2.invokeSuspend(EngineInterceptor.kt:77) 
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:34) 
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100) 
	at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:124) 
	at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:89) 
	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:586) 
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:820) 
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:717) 
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:704) 

NB : It seems Android rejection is hardcoded inside your version of okhttp3.internal.platform.Platform$Companion.findPlatform


Scenario 2 : Using impersonator bctls module only + vanilla OkHttp 4.12.0

Code

val trustManagerFactory = TrustManagerFactory.getInstance(
	TrustManagerFactory.getDefaultAlgorithm()
)
trustManagerFactory.init(null as KeyStore?)
val trustManagers: Array<TrustManager> = trustManagerFactory.trustManagers
if (trustManagers.size != 1 || trustManagers[0] !is X509TrustManager) {
	throw IllegalStateException("Unexpected default trust managers:" + trustManagers.contentToString());
}
val trustManager = trustManagers[0] as X509TrustManager

val api = ImpersonatorFactory.macChrome()
val sslContext = api.newSSLContext(null, null)

return OkHttpClient.Builder()
	.sslSocketFactory(sslContext.socketFactory, trustManager)
	.build()

Result A (using ImpersonatorFactory.macChrome() and ImpersonatorFactory.ios())

2026-02-08 20:05:24.687 26110-26261 CustomWebViewClient     me.devsaki.hentoid.debug             E  org.bouncycastle.tls.TlsFatalAlert: internal_error(80)
at org.bouncycastle.jsse.provider.ImpersonateTlsClientProtocol.updateKeyShareToClientHello(ImpersonateTlsClientProtocol.java:72)
at org.bouncycastle.jsse.provider.ImpersonateProvTlsClientProtocol.sendClientHelloMessage(ImpersonateProvTlsClientProtocol.java:41)
at org.bouncycastle.tls.TlsClientProtocol.sendClientHello(TlsClientProtocol.java:1966)
at org.bouncycastle.tls.TlsClientProtocol.beginHandshake(TlsClientProtocol.java:106)
at org.bouncycastle.tls.TlsClientProtocol.connect(TlsClientProtocol.java:84)
at org.bouncycastle.jsse.provider.ProvSSLSocketWrap.startHandshake(ProvSSLSocketWrap.java:610)
at org.bouncycastle.jsse.provider.ProvSSLSocketWrap.startHandshake(ProvSSLSocketWrap.java:586)
at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.kt:379)
at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.kt:337)
at okhttp3.internal.connection.RealConnection.connect(RealConnection.kt:209)
at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.kt:226)
at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:106)
at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.kt:74)
at okhttp3.internal.connection.RealCall.initExchange$okhttp(RealCall.kt:255)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:32)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:95)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201)
at okhttp3.internal.connection.RealCall.execute(RealCall.kt:154)
at me.devsaki.hentoid.util.network.HttpHelperKt.getOnlineResourceFast(HttpHelper.kt:163)
at me.devsaki.hentoid.activities.sources.CustomWebViewClient.parseResponse(CustomWebViewClient.kt:674)
at me.devsaki.hentoid.activities.sources.CustomWebViewClient.shouldInterceptRequestInternal(CustomWebViewClient.kt:565)
at me.devsaki.hentoid.activities.sources.CustomWebViewClient.shouldInterceptRequest(CustomWebViewClient.kt:506)
at WV.ng.a(chromium-SystemWebViewGoogle6432.aab-dev-766800003:101)
at org.chromium.android_webview.ShouldInterceptRequestMediator.shouldInterceptRequestFromNative(chromium-SystemWebViewGoogle6432.aab-dev-766800003:18)
Suppressed: org.bouncycastle.tls.TlsFatalAlert: internal_error(80)

Result B (using ImpersonatorFactory.macFirefox())

2026-02-08 20:07:30.654 27417-27570 CustomWebViewClient     me.devsaki.hentoid.debug             E  org.bouncycastle.tls.TlsFatalAlert: illegal_parameter(47); invalid key_share selected
at org.bouncycastle.tls.TlsClientProtocol.process13HelloRetryRequest(TlsClientProtocol.java:926)
at org.bouncycastle.tls.TlsClientProtocol.handleHandshakeMessage(TlsClientProtocol.java:485)
at org.bouncycastle.tls.TlsProtocol.processHandshakeQueue(TlsProtocol.java:709)
at org.bouncycastle.tls.TlsProtocol.processRecord(TlsProtocol.java:585)
at org.bouncycastle.tls.RecordStream.readRecord(RecordStream.java:247)
at org.bouncycastle.tls.TlsProtocol.safeReadRecord(TlsProtocol.java:864)
at org.bouncycastle.tls.TlsProtocol.blockForHandshake(TlsProtocol.java:421)
at org.bouncycastle.tls.TlsClientProtocol.connect(TlsClientProtocol.java:88)
at org.bouncycastle.jsse.provider.ProvSSLSocketWrap.startHandshake(ProvSSLSocketWrap.java:610)
at org.bouncycastle.jsse.provider.ProvSSLSocketWrap.startHandshake(ProvSSLSocketWrap.java:586)
at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.kt:379)
at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.kt:337)
at okhttp3.internal.connection.RealConnection.connect(RealConnection.kt:209)
at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.kt:226)
at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:106)
at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.kt:74)
at okhttp3.internal.connection.RealCall.initExchange$okhttp(RealCall.kt:255)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:32)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:95)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201)
at okhttp3.internal.connection.RealCall.execute(RealCall.kt:154)
at me.devsaki.hentoid.util.network.HttpHelperKt.getOnlineResourceFast(HttpHelper.kt:163)
at me.devsaki.hentoid.activities.sources.CustomWebViewClient.parseResponse(CustomWebViewClient.kt:674)
at me.devsaki.hentoid.activities.sources.CustomWebViewClient.shouldInterceptRequestInternal(CustomWebViewClient.kt:565)
at me.devsaki.hentoid.activities.sources.CustomWebViewClient.shouldInterceptRequest(CustomWebViewClient.kt:506)
at WV.ng.a(chromium-SystemWebViewGoogle6432.aab-dev-766800003:101)
at org.chromium.android_webview.ShouldInterceptRequestMediator.shouldInterceptRequestFromNative(chromium-SystemWebViewGoogle6432.aab-dev-766800003:18)
Suppressed: org.bouncycastle.tls.TlsFatalAlert: illegal_parameter(47); invalid key_share selected

Is there anything I'm doing wrong?

Should I add extra parameters or settings somewhere?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions