while running my app getting java.io.IOException: Hostname was not verified, how can i resolve it ?
java.io.IOException: Hostname '178.61.62.140' was not verified
01-03 16:34:37.613: W/System.err(17118): at libcore.net.http.HttpConnection.verifySecureSocketHostname(HttpConnection.java:224)
01-03 16:34:37.615: W/System.err(17118): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:454)
01-03 16:34:37.615: W/System.err(17118): at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:282)
01-03 16:34:37.616: W/System.err(17118): at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:232)
01-03 16:34:37.617: W/System.err(17118): at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:80)
01-03 16:34:37.617: W/System.err(17118): at libcore.net.http.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:194)
01-03 16:34:37.618: W/System.err(17118): at libcore.net.http.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:280)
01-03 16:34:37.618: W/System.err(17118): at com.axis.cbk.httpmodel.CustHttpClient.executeHttpPost(CustHttpClient.java:120)
01-03 16:34:37.619: W/System.err(17118): at com.axis.cbk.MainActivity$ProcessIt.doInBackground(MainActivity.java:237)
01-03 16:34:37.619: W/System.err(17118): at com.axis.cbk.MainActivity$ProcessIt.doInBackground(MainActivity.java:1)
01-03 16:34:37.621: W/System.err(17118): at android.os.AsyncTask$2.call(AsyncTask.java:264)
01-03 16:34:37.626: W/System.err(17118): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
01-03 16:34:37.626: W/System.err(17118): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
01-03 16:34:37.627: W/System.err(17118): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
01-03 16:34:37.628: W/System.err(17118): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
01-03 16:34:37.630: W/System.err(17118): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
01-03 16:34:37.631: W/System.err(17118): at java.lang.Thread.run(Thread.java:856)
01-03 16:34:37.632: I/System.out(17118): [CDS]close[48194]
01-03 16:34:37.633: I/System.out(17118): close [socket][/0.0.0.0:48194]
You're making an HTTPS connection with an IP address. Now, SSL certificates are bound to DNS hostnames and since you're not using a DNS hostname to connect, the certificate cannot be verified.
Use an actual DNS name to connect, or in some rare cases, write your own hostname verifier that accepts your host (careful: it's very easy to introduce vulnerabilities there).
@laalto's made some good points in his answer. There's also an alternative workaround that doesn't require any changes to your Android code which I've outlined below.
tl;dr - modify the /etc/hosts file on your Android device and add a new entry mapping your self signed cert common name to the IP address of your development server.
I've outlined the complete process below...
Create your certificate as usual with something like:
sudo openssl genrsa -out key.pem 2048
sudo openssl req -new -x509 -key key.pem -out cert.pem -days 1095
sudo cat key.pem cert.pem >> stunnel.pem
In the second command, set the common name to whatever domain name you want, for this example I'll use testssl.com .
I'm using stunnel to proxy my ssl connection so the 3rd command might not be applicable. Anyway, once your test website is using the cert you just created, open up a browser on your desktop and navigate to your site. As you'd expect you should get a security warning if everything's going as expected. View the certificate and export it as an X.509 certificate with chain (PEM) . Lets say we save it as testssl.com.
Now run the following command to convert it from the PEM format into a certificate format that you can download onto your Android device.
openssl x509 -inform PEM -outform DM -in testssl.com -out testssl.com.crt
Using adb you can now push your cert onto your device.
adb push testssl.com.crt /sdcard/testssl.com.crt
On your Android device go to Settings->Security->Install from device storage. You should be presented with the name you gave your cert, for me that's testssl.com.crt.
To modify your /etc/hosts file you'll need to remount your /system partition as read write and unfortunately you will need su for this.
adb shell
su
mount -o rw,remount /system
We'll put the /system partition back to read only later on.
Now lets grab the hosts file, modify it, and then put it back on the device with the following commands.
adb shell
su
dd if=/etc/hosts of=/sdcard/hosts
exit
exit
adb pull /sdcard/hosts
You can now add an additional line to your hosts file so that it looks something like [development_server_ip_address] [domain_name]. So assuming I used the settings detailed above and that my dev server has an IP of 192.168.1.10, then I'd add the following line to my hosts file:
192.168.1.10 testssl.com
You can now use your modified hosts file after running the following commands.
adb push hosts /sdcard/hosts
adb shell
su
dd if=/sdcard/hosts of=/etc/hosts
To make the /system partition read only run the following command from adb shell.
mount -o ro,remount /system
Now your Android app, along with any others that use an HTTPSUrlConnection object to connect to the domain name you added in your hosts file, shouldn't receive any certificate errors. And best of all you didn't have to change a single line of code.
Please note SSL Certificate work only by Domain not work by IP address.
if you use IP ,insert below code
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier()
{
@Override
public boolean verify(String hostname, SSLSession session)
{
if(hostname.equals("127.0.0.1 << your IP"))
return true;
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With