When I'm using the fetch function in my react native apps, things work as expected on iOS, but gives an error in android. The error is 'TypeError: Network request failed'. Doing a bit of debugging, I found that the cause of the error seems to be the following: 'java.security.cert.CertPathValidatorException: Trust anchor for certification path not found'.
How come this works in iOS and not on android, and how do I best fix it? Is the fault in react-native, or somewhere deeper?
There is a few workarounds for this issue mentioned here: Trust Anchor not found for Android SSL Connection
However, if you are the server owner. I would suggest to review your server ssl certificate. I think that was because of missing CA certificate in your pem file.
What I have done for my site is I created fullchain.pem by concating content of file.crt and file.ca-bundle as that order.
Then I configure nginx (my server behind nginx) with:
ssl_certificate /etc/nginx/ssl/fullchain.pem;
The original document: https://www.digicert.com/ssl-certificate-installation-nginx.htm
Hope that helps
Related
I am trying to connect via SSL and certificate to have a solid and secure connection but apparently it is not as simple as it looks like.
Using python is 100% working and can test the connecton by using these paramters
client.tls_set(ca_certs="x.pem", certfile="/y.pem.crt", keyfile="z.pem.key", cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLSv1_2,ciphers=None)
client.tls_insecure_set(True)
I was applying different varian of code found on the internet and even on here and applying the SSLSocketFactory on my MqttConnectOptions.
Common errors were like "SSL path not found" ( yes I did check if the code was reading the file and it worked ), "Trust anchor for certification path not found." and so on....
I also had issue to parse the key file to PemParse due to be in the resources but with not much luck.
This one of the link I was following as well https://gist.github.com/sharonbn/4104301 but with no much success.
Just to "complicate things", my certificate are without password and most of the examples on the web are with.
To recap:
I have x.pem, y-private.pem.key, z-certificate.pem.crt, u-public.pem.key
With python works fine
Android is not working or at least I am not able to.
In case it wasnt clean, I am after a piece of code that allows me to use the certificates above to add to my MqttConnectOptions and make a successfully connection to the server.
I am a little new to this whole WebSocket and SSL certificate.
So I have created my own WebSocket server on Android side and the website is the client. I was able to make it work with regular WebSocket (ws://) but not secure WebSocket (wss://) due to the fact that it requires SSL certificate.
My question is how can I get a SSL certificate? From what I've read, SSL certificate is based on a domain. I need it for localhost. I need it for something like this address:
wss://localhost:8080/ws/main
How can I go about getting a SSL certificate that will work with localhost.
Thank you for your time!
====================== EDIT =====================
Reason why I am doing this:
I have a Bluetooth service in my Android application that will be getting data from connected health bluetooth devices like Weight Scale and Blood Pressure machine. I have this part implemented already and I want to take this data and pass it to a website. WebSocket seemed easier because the user will have my application open and when they do their weight, it would automatically fill the field on the website with the weight from the Weight Scale. I hope I am making this clear.
To do this, I need to have a way to pass the weight or blood pressure values from Java (Android) to the website that loads within a WebView. So I thought WebSocket would the easiest way.
Please tell me if you think there is an easier way.
Also, I've already tried self-signed certificate and I get the following error:
I/X509Util: Failed to validate the certificate chain, error: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
OR
Exception=javax.net.ssl.SSLException: Error occured in delegated task:javax.net.ssl.SSLException: Not trusted server certificate
Thank you!!!
We faced a similar problem, our solution was to register a subdomain to one of our domains with an A record to 127.0.0.1 and get a certificate for that domain.
local.example.com -> A record to 127.0.0.1
SSL certificate requested for local.example.com
I'm afraid this answer is too late for you however, it can be helpful for others finding this article.
I have a little problem with Volley. I'm trying to get the response from some url which is fully working on mobile browser.
Meanwhile in my application I'm getting an error:
ERROR: com.android.volley.NoConnectionError: javax.net.ssl.SSLHandshakeException: Signature uses an insecure hash function
Is there a way to solve it in an application or should I contact with my backend provider?
I did a little digging and found that:
Google is now blacklisting weak hash functions in SSL certs and throwing exceptions when trying to communicate with the problem server. Whereas before, it was silently ignored.
Source
With that in mind, you could try doing this to teach HttpsURLConnection to trust a specific set of CAs.
But in the end, I believe that its your backend providers fault in providing a insecure hash function. So, before trying a huge workaround maybe contacting your backend provider would be the easier way out.
Hope it helps.
I have two domains: foo.net and bar.com. They both have SSL certificates, and they work well in all desktop and mobile browsers. They are hosted on the same server configured with nginx.
However, when I make a request to a domain from within a native android app, it somehow gets the certificate from the wrong domain! This results in an IO Exception:
request = new HttpPost("https://foo.net/api/v1/baz");
request.setHeader("Authorization", "user:pass");
response = httpClient.execute(request);
...
javax.net.ssl.SSLException: hostname in certificate didn't match: <foo.net> != <bar.com> OR <bar.com> OR <www.bar.com>
What would cause android/java to try using the certificate from bar.com when every other measure seems to indicate that the server is correctly configured? Nothing appears in the nginx access or error log. There is no mention of bar.com anywhere in my android project.
Edit: I'm not sure why, but it appears that the server is using the certificate for bar.com for the server IP https://198.245.xx.xxx
The most likely cause for this problem is that the server uses Server Name Indication to choose which certificate to send. If the client doesn't support SNI, the server cannot choose which certificate to send during the SSL/TLS handshake (before any HTTP traffic is sent). SNI is required when you want to use multiple certificates on the same IP address and port, but not all clients support it (notoriously, IE on any version of Windows XP, and a number of mobile browsers).
You're also visibly using the Apache HTTP Client library (not HttpsURLConnection, for which there can be SNI support with some Android versions.
Support for SNI in the Apache HTTP Client library is quite recent, and certainly hasn't made it into the Android stack.
You may find the workaround described in this article useful (although it seems only to work for Android 4.2+).
Another two options would be:
to use a distinct IP address for each host (so as not to need SNI), if you're in control of server, or
to use another HTTP Client library (e.g. HttpsURLConnection).
A solution for Apache, more like a trick:
the SSL certificates are loaded based on the vhost name from /etc/apache2/sites-enabled. So, to trick that check make sure the problematic certificate is loaded first (remember that the vhosts are loaded by name).
It looks like the certificate of foo.net is misconfigured, and is using the same hostname as bar.com
Try to run an online certificate validation tool, like https://www.digicert.com/help/ on foo.net, just to be sure.
I think that you need to regenerate the certificate of foo.net with the right hostname, or reconfigure ngix to make sure that nginx serve the right certificate for the right host.
Scenario: I am trying to debug an Android app by proxying requests through Fiddler.
I got FiddlerRoot certificate installed on the Android device, and the SSL decryption works for most requests, but for other requests I can only see the HTTPS Connect, and nothing else in the Fiddler log. I think it might be image requests over SSL that fails to decrypt.
I have double-checked that "Hide images" is off, etc. Images retrieved are hosted on another domain than the main API the app talks to.
What could cause this behaviour ? And how do I get the image requests to show in Fiddler ?
I am using the latest Fiddler4.
There are plenty of tutorials on how you can intercept HTTP(s) traffic from Android using Fiddler.
Try this one: http://docs.telerik.com/fiddler/configure-fiddler/tasks/configureforandroid
However, it will fail when you try to intercept and decrypt Android SSL traffic coming from an application, and not from a browser.
It might be that the application uses a certificate pinning – and you are probably cannot decipher this connection. Lost cause!
But more probably, the reason is a bug in the HttpsUrlConnection pipeline implementation.
To solve the issue, please proceed with the following steps:
In Fiddler click "Rules->Customize Rules";
Find function OnBeforeResponse in the script
Add following code to the function body:
if (oSession.oRequest["User-Agent"].indexOf("Dalvik") > -1 &&
oSession.HTTPMethodIs("CONNECT")) {
oSession.oResponse.headers["Connection"] = "Keep-Alive";
}
Save the file and restart Fiddler.