0

My Android app tells me that my https certificate doesn't match the hostname:

javax.net.ssl.SSLException: hostname in certificate didn't match: <hostname1> != <oldhostname>

What is odd is that

  1. The website (hostname1) gives the correct certificate (checked with browsers and the ssllabs tool)
  2. oldhostname is the previous hostname I had set up in previous versions of the app

Is there some kind of cache for certificates? I cant't find any info on that

René
  • 179
  • 8
  • Are you sure that you are running the code that has the URL using `hostname1` instead of `oldhostname`? Your symptoms would fit a case where your Java code is still using `oldhostname`. – CommonsWare Apr 17 '16 at 14:14
  • This can be a problem of a wrong URL in which case you would get a similar error in the browser. Or it is a problem with SNI, see http://stackoverflow.com/questions/5879894/android-ssl-sni-support. – Steffen Ullrich Apr 17 '16 at 14:26
  • Yes I'm sure the URL is correct. I'm rather sure Steffen is right, I took a very quick glance at SNI/Android some time ago and I understood that for anything above 2.x it was OK. Looks like I misunderstood what I read, I'll take the time to thoroughly read the link. Thanks a lot Steffen – René Apr 17 '16 at 18:51

1 Answers1

0

Add this class

public class HttpsTrustManager implements X509TrustManager {
    private static TrustManager[] trustManagers;
    private static final X509Certificate[] _AcceptedIssuers = new X509Certificate[]{};

    @Override
    public void checkClientTrusted(
            X509Certificate[] x509Certificates, String s)
            throws java.security.cert.CertificateException {
    }

    @Override
    public void checkServerTrusted(
            X509Certificate[] x509Certificates, String s)
            throws java.security.cert.CertificateException {
    }

    public boolean isClientTrusted(X509Certificate[] chain) {
        return true;
    }

    public boolean isServerTrusted(X509Certificate[] chain) {
        return true;
    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return _AcceptedIssuers;
    }

    public static void allowAllSSL() {
        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {

            @Override
            public boolean verify(String arg0, SSLSession arg1) {
                return true;
            }

        });

        SSLContext context = null;
        if (trustManagers == null) {
            trustManagers = new TrustManager[]{new HttpsTrustManager()};
        }

        try {
            context = SSLContext.getInstance("TLS");
            context.init(null, trustManagers, new SecureRandom());
        } catch (NoSuchAlgorithmException | KeyManagementException e) {
            e.printStackTrace();
        }

        HttpsURLConnection.setDefaultSSLSocketFactory(context != null ? context.getSocketFactory() : null);
    }
}

and call it from your MainActivity with HttpsTrustManager.allowAllSSL();

Although it's not save approach but i solve my problem with this.

Umer
  • 1,566
  • 2
  • 20
  • 31
  • With this kind of "workaround" you are welcome in the club of insecure applications, see https://www.fireeye.com/blog/threat-research/2014/08/ssl-vulnerabilities-who-listens-when-android-applications-talk.html or http://www2.dcsec.uni-hannover.de/files/android/p50-fahl.pdf. – Steffen Ullrich Apr 17 '16 at 14:24
  • @SteffenUllrich Yes i mention it in my answer that "it's not save approach" if you have any good approach let us know. – Umer Apr 17 '16 at 14:27
  • The correct approach is to find out the cause of the error first and then fix the cause instead of simply ignoring the problem by disabling certificate validation. – Steffen Ullrich Apr 17 '16 at 14:28