How to debug TLS negotiation failure with load-balancer? - android

I have an Android app which communicates to a backend server via HTTP POST requests. I would like to upgrade it to HTTPS. The API I'm using is HttpLib.postRequest.
I'm finding that a direct connection to my Apache server works fine. But a connection via a load balancer doesn't work. My load balancer is from Aliyun. I've tried two different load balancers, both fail the same way. The direct symptom is that I get an "unknown_err" on the phone.
I can capture traffic with tcpdump, which proves that it's connecting to the correct place and attempting to negotiate. The session ends with the client sending an HTTPS error "Certificate Unknown (46)".
Normally this is caused by bad certificates or configuration. But I know that my certificates are all valid. Other browsers work fine connecting to the same server to load normal web pages. And the iOS version of the same app also works fine. Browsing to the web site on an Android phone works fine even when the app is failing to connect. The website is https://zaomengshe.com so you can check the certificate there. I also have a different setup with a load balancer and a certificate from Let's Encrypt.
I guess there is some peculiarity of Aliyun's load balancers and Android that's preventing a successful negotiation. Perhaps I need to enable support for some algorithm or key size or something. I did read that TLS 1.2 wasn't supported until API version 20, so I updated the minimum supported version to 20. That didn't help.

The report by SSLLabs for this domain clearly says:
This server's certificate chain is incomplete. Grade capped to B.
The reason for this problem is probably a messed up configuration at the load balancer: only the leaf certificate is served inside the TLS handshake but not the intermediate certificates needed to build the trust chain. Desktop browser usually try to work around such broken configurations but other applications usually don't.
This means that this is very likely the reason your application fails. And the issue need to be fixed at the load balancer by also configuring the intermediate certificates.

Related

How to add self-signed certificate on Android 10 (MIUI 12) for local development and debugging

Could you suggest how to add a self-signed certificate on Android (MIUI 12, Android 10).
There is a mobile app for Android, and a backend written in symfony. We have a bug that is very difficult to catch, and it is not clear whether it is a bug in the app or a problem in the backend. Currently, it is not known which endpoints in which order the mobile app calls. When I test my local backend through postman, everything works as expected (there is no bug). When I test on Android (which is directed to the stage), I can see a bug. Hence, it was decided to build the application directed to local backend by replacing the api-url with the hostname of my laptop. Then the requests would go over the local network to the local backend, where it would be possible to debug what exactly is happening. But once we've built the app, it turned out that it's not that simple to send requests to the local backend since a self-signed certificate is used. I tried to add this certificate to the android config, but nothing changed. Though, certificate shows up in the list. Maybe I made some mistakes when converting that certificate (because xiaomi doesn't allow to import a .crt file), or maybe it's backend that is configured incorrectly.
Can anyone who has encountered such a problem tell me how to set the environment up correctly. Maybe there is some guide on this topic.
PS. It is not an option to use Ngrok, because it will be necessary to distract the mobile team every time in order to build the application with the new url.

Android: Connecting to Squid proxy with SSL bumping not working

I have a Squid proxy installed with HTTPS/SSL. When I install the generated certificate in Firefox and set the proxy, everything looks good -- that is, I can see all the HTTPS requests the Squid log files.
However, when I install the same certificate in my Android phone (and change the proxy setting), it seems to work only in the browser. I first change the proxy setting and pages didn't load, then I installed the certificate and all was good.
All other app I've tried yield in errors due to connection problems. I can see the CONNECT request in the Squid logs but no other requests (e.g., GET, POST). I know that some app completely ignore the system proxy settings, but many use them.
The odd thing is that everything was working on an old Android 6.0 phone. Here the same apps where working perfectly fine using the proxy and relying on HTTPS requests. Now I have a newer Android 9.0 phone and all apps so far fail. The apps obviously use the proxy (seeing the CONNECT entries in the logs) but do not use/acknowledge the installed certificate.
I currently see the new phone or the new Android version as cause for the problem since it worked before with an older phone and Android version. How can I best track this issue down?
"Since Android 7, apps ignore user provided certificates, unless they are configured to use them. As most applications do not explicitly opt in to use user certificates [...] we need to place our CA certificate in the system certificate store"
https://docs.mitmproxy.org/stable/howto-install-system-trusted-ca-android/
However, this seems not to be easily done...
Android connects to specific domains to verify the connection.
Add this bit to the the squid.conf:
# Mobile
acl google-servers dstdom_regex "/etc/squid/google.txt"
always_direct allow google-servers
next, create this file /etc/squid/google.txt with the following content:
(^|\.)android\.clients\.google\.com$
(^|\.)ggpht\.com$
(^|\.)google\.com$
(^|\.)www\.googleapis\.com$
(^|\.)gstatic\.com$
(^|\.)gvt1\.com$
(^|\.)1e100\.net$
(^|\.)google\.co\.uk$
to activate, run:
./squid -k reconfigure

Android w React-Native: secure fetch request fails

I'm working on a native app for iOS and Android using React-Native. I have to hit a third-party REST API that uses https:// protocol. There is a staging server and a production server for the API.
I have success making requests to both servers on iOS. On Android, I can access staging, but not production. Requests to both servers are successful using Postman.
Requests to production on Android give me the infamous [TypeError: Network request failed] message. I looked around on this site and elsewhere, and learned that this is usually the result of a certificate trust issue (which is not something I'm super knowledgeable about). I used openssl to view the certificates and did see three certs when checking staging, and only two for production. I tried following the custom TrustManager example on the Android HTTPS and SSL page: https://developer.android.com/training/articles/security-ssl.html
As well as this tutorial for SSL pinning: https://medium.com/the-many/a-year-of-react-native-ssl-pinning-3801a973cbfe
No luck. I should probably mention that at no point have I seen any logcat messages referring to certificate trust errors, so I'm not even entirely sure this is my issue.. it's just the only thing that makes sense based on what I've been able to find out. I tried going to Android Studio Preferences > Tools > Server Certificates and enabled 'Accept non-trusted certificates automatically' as a sanity check for testing. Still no luck and no change in log messages.
The requests are formatted exactly the same in React-Native, and are successful in three out of four of my scenarios (iOS staging & prod, Android staging). What am I missing?

Ionic Android app has no internet access on signed release apk but debug works fine

My app works fine in the debug apk, but as soon as I build and sign a release version, my app has no internet access and no requests work. All requests are made over https.
My server uses https on nginx to reverse proxy requests to a node.js server. I looked at other issues and they say it has something to do with interimediate ssl certificate problems on the server. I'm rather new to configuring ssl and I'm not sure what that means or how to fix it, but the server works fine normally over https.
Sorry, I got this fixed a long time ago. I contacted Comodo customer support and they gave me the correct root and intermediate certs to use. I guess there's something that blocks ssl certificates that don't have a full keychain back to the CA.
So anyone else having this issue, just contact your CA and ask them for the proper intermediate and/or root certificates.

Cannot access my Server with ssl url

I am developing an iOS & Android Application with React Native. I use to access my backend server with "normal" url -> http:// ....
Now since i have changed it and added ssl i need to use my new backend url with ssl which is https://
On iOS everything works like it should. The problems are caused by my android app.
I am not sure how to solve this. Is there anything i have to do to access ssl based urls for android? Maybe in my Manifest or something? Any hints would be great...
Android doesn't want to trust server's certificate.
Which Android version you'd tested?
Older versions like 4.1.x haven't installed 'less known' CA's.
Try it with Marshmallow.
To fix it you can always install a proper certificate on the device by hand (settings->security->load ca from sdcard) or change CA on the server to one which is more 'known' (probably more expensive).
BTW. Check out the logs. It should fail on SSl handshake.
Another test you can do is publishing a simple website by this server and try running this website over https on affected Android device. If the system doesn't trust it browser will alert you about that. For instance:

Categories

Resources