Https Get (Ssl) with Android and Self-Signed Server Certificate

Android SSL HTTP Request using self signed cert and CA

Solved by using: HttpsURLConnection

URLConnection conn = null;
URL url = new URL(strURL);
conn = url.openConnection();
HttpsURLConnection httpsConn = (HttpsURLConnection) conn;

This seems to work fine with user installed CA certificates.

Android - Obtain self-signed server certificate and add to trusted keystore

The simple solution

Here's a code example of a trust manager callback. From the callback you can either store the self-signed certificates or just accept them right away. But you SHOULD NOT do neither. By accepting self-signed certs, you are subject to connecting to fake or malicious servers which can steal personal data, install malware, and do other nasty things.

The better-than-simple solution

If a server offers a self-signed certificate that you, the developer, trust at compile time, you can bundle the cert into the app like you're already doing. It would be much better if the server had a CA-signed certificate, but if you really need to connect to a server that offers a self-signed cert, this will (have to) do.

A nicer solution

Never accept self-signed certificates in runtime. If you want to allow your users to connect to these kind of servers, you can show a warning message like "proceed at your own risk" before accepting the self-signed cert.

accepting HTTPS connections with self-signed certificates

The first thing you need to do is to set the level of verification.
Such levels is not so much:

  • ALLOW_ALL_HOSTNAME_VERIFIER
  • BROWSER_COMPATIBLE_HOSTNAME_VERIFIER
  • STRICT_HOSTNAME_VERIFIER

Although the method setHostnameVerifier() is obsolete for new library apache, but for version in Android SDK is normal.
And so we take ALLOW_ALL_HOSTNAME_VERIFIER and set it in the method factory SSLSocketFactory.setHostnameVerifier().

Next, You need set our factory for the protocol to https. To do this, simply call the SchemeRegistry.register() method.

Then you need to create a DefaultHttpClient with SingleClientConnManager.
Also in the code below you can see that on default will also use our flag (ALLOW_ALL_HOSTNAME_VERIFIER) by the method HttpsURLConnection.setDefaultHostnameVerifier()

Below code works for me:

HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;

DefaultHttpClient client = new DefaultHttpClient();

SchemeRegistry registry = new SchemeRegistry();
SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
socketFactory.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier);
registry.register(new Scheme("https", socketFactory, 443));
SingleClientConnManager mgr = new SingleClientConnManager(client.getParams(), registry);
DefaultHttpClient httpClient = new DefaultHttpClient(mgr, client.getParams());

// Set verifier
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);

// Example send http request
final String url = "https://encrypted.google.com/";
HttpPost httpPost = new HttpPost(url);
HttpResponse response = httpClient.execute(httpPost);

Trust my own self-signed certificate in local network using Android Native, Android Studio and retrofit

Shlomi Katriel's answer was something I had already tried, but it led me to the solution indirectly. Please keep in mind that the only reason I was able to solve this was because I have root access to the server and can do with it as I please.

This
answer was basically the key to solving the whole thing. I will post all the steps in case someone else needs this.

Step 1
Create your self-signed certificate. In my case, I used the openssl utility. It is very important to include the -addext flag. Here is an example taken directly from the answer I linked above:

openssl req \
-newkey rsa:2048 \
-nodes \
-x509 \
-days 36500 -nodes \
-addext "subjectAltName = IP.1:1.2.3.4" \
-keyout /etc/ssl/private/nginx-selfsigned2.key \
-out /etc/ssl/certs/nginx-selfsigned2.crt

Replace 1.2.3.4 with the local ip of your server. This will include the server's local ip in the subjectAltName property of the certificate. Without this, you will keep getting the error "Hostname ... not verified ..."

Using the certificate in a running nginx instance is a different subject which can be done easily and there are plenty of resources online.

Step 2 Open android studio and create a new android resource directory (if you don't already have it) under res named raw. Inside this directory, copy the contents of the .crt file that the command above produced.

Step 3 Create an android resource directory under res named xml. In there, create a new xml file which in my case I called network_security_config.xml. In there, I inserted the following:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="false">
<trust-anchors>
<certificates src="@raw/certificate"/>
<certificates src="system"/>
</trust-anchors>
</base-config>
</network-security-config>

Instead of "certificate", use the filename of the certificate file you copied in step 2.

Step 4 Add android:networkSecurityConfig="@xml/network_security_config" to the application element in your AndroidManifest.xml

android - https with server having self-signed certificate

Do I have separately get my server's self-signed certificate ?

I don't know what "separately" means in this context, but you need the keystore containing the self-signed certificate for the purposes of validation.

Will the API not get that for me automatically in some way ?

How could it? The point behind validating a certificate is to confirm that it is indeed correct, and that your user is not the victim of a man-in-the-middle attack. To do that for a self-signed certificate, we need the relevant details to make that validation.

FWIW, if you find this stuff to be a bit complex to set up, I have a TrustManagerBuilder in my CWAC-Security library that can help a bit.

android studio: https self signed certificate not trusted

So I figured it out, altough i did enable self signed certificate on android studio, I didnt enable them on kotlin, so the error came from kotlin and not android studio, a quick copy-paste from this answer

has solved it, altough I dont understand a thing from it, and if someone could send me a refrence to some sort of explantion or a tutorial for it that would be wonderful.

Setting up an HTTPS connection on Android with a self signed certificate from an AWS server

Heres how I got the certificate, although this answer may not be very helpful to others. I asked the server admin for it and he gave it to me. I believe he generated the certificate from some bash code while he was SSHed into the server. I then created an assets folder in main and drop the certificate file in there. I got the input stream with this line of code InputStream in = context.getAssets().open("my_cert.crt").

HTTPS with Self-Signed SSL Certificate Issues... Solution or better way?

I found two great examples of how to accept self-signed SSL certificates, one each for HttpsURLConnection and HttpClient.

HttpsURLConnection solution: Https Connection Android

HttpClient solution: Self-signed SSL acceptance on Android



Related Topics



Leave a reply



Submit