I am connecting to a server which has TLS support with SSL certs. I am getting a SSL Handshake error on Android app client. I also use useTransportSecurity() to deal with TLS negotiation type. Is there any workaround to get away with this error without certificate pinning?
Error encountered:
Caused by: java.lang.RuntimeException: protocol negotiation failed
at io.grpc.okhttp.OkHttpProtocolNegotiator.negotiate(OkHttpProtocolNegotiator.java:96)
at io.grpc.okhttp.OkHttpProtocolNegotiator$AndroidNegotiator.negotiate(OkHttpProtocolNegotiator.java:147)
at io.grpc.okhttp.OkHttpTlsUpgrader.upgrade(OkHttpTlsUpgrader.java:63)
at io.grpc.okhttp.OkHttpClientTransport$2.run(OkHttpClientTransport.java:474)
at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:123)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
And this is how I generate my channel :
ManagedChannel mChannel = OkHttpChannelBuilder.forAddress(host, port)
.useTransportSecurity()
.build();
Appreciate your time and help.
ALPN is failing during the TLS handshake, which prevents gRPC from negotiating HTTP/2. Either you aren't connecting to a gRPC / HTTP/2 server or your client's TLS library is too old.
Please review the SECURITY.md documentation. Namely, you probably want to "install" the Play Services Dynamic Security Provider into the runtime when your app starts.
it might be rather a matter how you create the server; see SECURITY.md for Mutual TLS ...
Server server = NettyServerBuilder.forPort(8443)
.sslContext(GrpcSslContexts.forServer(certChainFile, privateKeyFile)
.trustManager(clientCAsFile)
.clientAuth(ClientAuth.REQUIRE)
.build());
Answering my own question.
This error comes from the ALPN TLS extension, which I needed my SSL endpoint to support. I was using NPN, and that is why I was unable to connect.
Posted by Carl Mastrangelo in grpc.io google groups
Related
This question already has answers here:
Trust Anchor not found for Android SSL Connection
(22 answers)
Closed 2 years ago.
EDIT
It does not seem to be a duplicate to me since all the other questions are related with repeatable issues and not intermittent like this one
END-EDIT
I have an app that runs some HTTP GET.
The app runs on API 21+.
It works fine most of the time, but very rarely one HTTP GET fails with the error:
D/OkHttp: --> GET https://url/url2?parm1=value1
D/OkHttp: --> END GET
D/OkHttp: <-- HTTP FAILED: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
When this starts happening, it keeps happening until I kill the app.
I'm using Retrofit with OKHttp 4.3.1. I'm going to update to the latest version now just in case this is a bug in OKHttp but I didn't find any report.
The code for the HTTP call is the usual code with Retrofit:
private val retrofit: Retrofit
get() = Retrofit.Builder()
.baseUrl(BuildConfig.BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(CoroutineCallAdapterFactory())
.client(client)
.build()
internal val service: AppService
get() = retrofit.create<AppService>(AppService::class.java)
internal interface AppService {
#GET
suspend fun loadServerListAsync(#Url url: String): Response<List<Server>>
}
In the past I have seen this error in another app. In that case the error wasn't intermittent and the problem was on the backend: they had changed a certificate, but they hadn't updated all the intermediate certificates.
In this case it looks like the error is different since it is intermittent and killing the app fixes it. There is no load balancer on the backend so it can't be that different servers have different certificates.
It can be related from cypher security protocol TLSv1 to fail and fallback to deprecated SSLv3.
To prevent TLSv1 secure connection to fallback to SSLv3 in simulator and throw connection error because SSLv3 is now deprecated and unsecure (Android Studio Failure in SSL library, usually a protocol error)
Install updated security provider using Google Play Services.
This effectively gives your app access to a newer version of OpenSSL and Java Security Provider, which includes support for TLSv1.2 in SSLEngine.
Once the new provider is installed, you can create an SSLEngine which supports SSLv3, TLSv1, TLSv1.1 and TLSv1.2 the usual way.
This should be the answer to your problem : Javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: Failure in SSL library, usually a protocol error
I have configured android APP to bypass certificate pinning using some modification of app and installed mitm certificate as system and user in android
After running mitmproxy and mitmdump i got below error
however i tried all possible way to solve issue but only in one app i am facing this error
Certificate verification error for www.kjljjlk.com.mx:
("hostname 'www.hjkhjk.com.mx' doesn't match either
of 'a248.e.jhkhkdsfsf.net', '*.dsfsfds-sdfsdfdsf.net',
'*.sdffdsfsdf.net', '*.dsfsdfdsf-sdfsfsf.net',
'*.dfsfsdsdf.net'",)
<< Cannot establish TLS with client (sni: xyxyxyxy.com): TlsException("SSL handshake error: Error([('SSL routines', 'tls_process_client_hello', 'parse tlsext')])")
I also try to run with burpsuite, but i get unknown_ca error
After all i tried to open site in firefox, and i get warning of potential risk
xyxyxyx.com uses an invalid security certificate. The certificate is
not trusted because it is self-signed. Error code:
MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT
so i click on accept risk and continue, then it open
but somehow in android app it is not accessing site
any help pls
Thank you
======
> Mitmproxy: 5.0.0 binary Python: 3.7.5 OpenSSL: OpenSSL 1.1.0j 20
> Nov 2018 Platform:
> Linux-5.3.0-7625-generic-x86_64-with-debian-buster-sid
As a general rule, you can disable certificate checking with the ssl_insecure option.
What TLS versions are supported by the server? It might be that the server is TLS 1.3 only, which mitmproxy doesn't support at the moment (https://github.com/mitmproxy/mitmproxy/pull/3692).
#MaximilianHils
from mitmproxy import options
from mitmproxy import proxy
from mitmproxy.tools import dump
myaddon = Myaddon()
prot = sys.argv[1]
opts = options.Options(listen_port=int(prot), ssl_insecure=True, http2=False)
pconf = proxy.config.ProxyConfig(opts)
m = dump.DumpMaster(opts)
m.server = proxy.server.ProxyServer(pconf)
m.addons.add(myaddon)
I'm making an app for Android 4.4 and above, and I'm trying to do an https request, I first tried with Retrofit and it gives me this:
V/error: javax.net.ssl.SSLHandshakeException: Handshake failed
I thoug it was something about the Retrofit API, but later I tried with Volley and it gives me this:
SSL handshake aborted: ssl=0xf311e9c8: Failure in SSL library, usually a protocol error
error:10000410:SSL routines:OPENSSL_internal:SSLV3_ALERT_HANDSHAKE_FAILURE (third_party/openssl/boringssl/src/ssl/tls_record.cc:562 0xd4fba9c8:0x00000001)
error:1000009a:SSL routines:OPENSSL_internal:HANDSHAKE_FAILURE_ON_CLIENT_HELLO (third_party/openssl/boringssl/src/ssl/handshake.cc:464 0xd7936bd8:0x00000000)
12-29 16:37:53.551 13763-14823/xxx.xxx.xx I/qtaguid: Untagging socket 47
12-29 16:37:53.571 13763-13763/xxx.xx.xx V/error: javax.net.ssl.SSLHandshakeException: Handshake failed
In fact, is the same issue, I don't know if I need add something to my app, due this request works perfectly with postman.
The weird thing is, before we migrate the services to the new server, I was working with a server with HTTP and it works perfectly. I don't know what I must add about security to my app.
Given an Android app that uses httpclient to connect to a third party web site, how can I get a successful SSL connection from an older Android device?
Earlier, both current and older Android versions worked, but the third party web site changed their SSL configuration. This precipitated an error, but only on the older Android platforms:
System.err: javax.net.ssl.SSLException: Connection closed by peer
System.err: at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
System.err: at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:406)
After doing some research (google issue tracker), I thought I might try to remove SSLv3 from the list of available protocols. I have been able to do that, and also have narrowed the number of cipher suites, but still have the SSLException problem.
The code, which uses httpclient-4.4.1.2, is patched to allow SNI, and works on newer Android (API 22), but not on an older Android (API 15) is this:
nHttpclient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).setDefaultCookieStore(nCookieStore).build();
Here is some code I've been experimenting with. Although I am able to remove SSLv3, I'm still unable to establish a secure connection:
HttpClientBuilder clientBuilder = HttpClientBuilder.create();
SSLContextBuilder contextBuilder = SSLContextBuilder.create();
contextBuilder.useProtocol("TLSv1");
SSLContext sslContext = contextBuilder.build();
clientBuilder.setSslcontext(sslContext);
nHttpclient = clientBuilder.setRedirectStrategy(new LaxRedirectStrategy()).setDefaultCookieStore(nCookieStore).build();
The above code limits the protocols to include TLSv1 (no longer includes SSLv3. Also, I have temporarily altered SSLConnectionSocketFactory.createLayeredSocket() so that the socket only includes cipher suites included in both new and old Android platforms. In other words, I removed a bunch of suites that were not reported as available on a new Android platform.
So, limiting to TLSv1 and limiting to newer cipher suites, I'm still getting the error and am not able to establish a secure connection.
Logging on older Android:
cz.msebera.android.httpclient.conn.ssl.SSLConnectionSocketFactory: Enabled protocols: [TLSv1]
cz.msebera.android.httpclient.conn.ssl.SSLConnectionSocketFactory: !!Enabled cipher suites:[TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
cz.msebera.android.httpclient.conn.ssl.SSLConnectionSocketFactory: Starting handshake
cz.msebera.android.httpclient.impl.conn.DefaultManagedHttpClientConnection: http-outgoing-1: Shutdown connection
cz.msebera.android.httpclient.impl.execchain.MainClientExec: Connection discarded
cz.msebera.android.httpclient.impl.conn.DefaultManagedHttpClientConnection: http-outgoing-1: Close connection
The same code running on newer Android:
cz.msebera.android.httpclient.conn.ssl.SSLConnectionSocketFactory: Enabled protocols: [TLSv1, TLSv1.1, TLSv1.2]
cz.msebera.android.httpclient.conn.ssl.SSLConnectionSocketFactory: Enabled cipher suites:[TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
cz.msebera.android.httpclient.conn.ssl.SSLConnectionSocketFactory: Starting handshake
cz.msebera.android.httpclient.conn.ssl.SSLConnectionSocketFactory: Secure session established
Summary
It must be a common problem to enable older Android platforms to be able to use httpclient-4.4.1.2 (or similar) when the sites being accessed have been updated to newer SSL/TLS standards.
My experiments with API 15 indicate that having httpclient code that manages SNI, where SSLv3 is removed, and where older cipher suites are removed still does not allow a secure connection, but instead throws a SSLException in SSL_do_handshake().
If I try to force the old Android to use TLSv1.1, I get:
java.security.NoSuchAlgorithmException: SSLContext TLSv1.1 implementation not found
My research indicates that API 15 or lower is just never going to work with TLSv1.1 and higher, but that API 16 through API 19 might work, but the newer protocol is not enabled by default. API 20 and higher, the newer protocol is enabled by default.
What needs to be done to allow a secure connection from httpclient on Android OS's in the API 16 range?
The problem is that httpclient-android code uses getEnabledProtocols() instead of getSupportedProtocols().
The work around that I employed was to get the source code for smarek httpclient-android, pull that into a module of my project, remove the reference to the pre-built version of httpclient-android, then change one line in SSLConnectionSocketFactory.java :
//final String[] allProtocols = sslsock.getEnabledProtocols();
final String[] allProtocols = sslsock.getSupportedProtocols();
This had the effect of allowing connection to the third party web site I was trying to access on API's 16, 17, 18 and 19.
I think that Accessing TLSv1.1 or TLSV1.2 from API 15 or less is "impossible" unless you're willing to do some serious changes at the Android OS level.
But this simple change allows apps running on older Android versions to access sites that no longer support older SSL and TLSv1.
I want to make volley https request, and I have use code from here to remove SSL3 protocol and using TLSv1.2 for android >=4.4 and TLS for Android<4.4, but sometimes when I make request this error appear :
javax.net.ssl.SSLHandshakeException:
javax.net.ssl.SSLProtocolException: SSL handshake terminated:
ssl=0x606cfb30: Failure in SSL library, usually a protocol error
error:1409443E:SSL routines:SSL3_READ_BYTES:tlsv1 alert inappropriate
fallback (external/openssl/ssl/s3_pkt.c:1256 0x5fee2098:0x00000003)
anybody can help ?
Note : That error only appear in some device with Android 4.4, some other device with Android 4.4 is working well without that error.
Finally, I found it by myself, that just the problem when using slow connection, so when the connection timeout volley handshake will failed (volley connection time out is so fast), so I try to added Volley time out to 10000 ms, like this :
jsonRequest.setRetryPolicy(new DefaultRetryPolicy(10000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
And now my app working in device that use slow connection too.