How can I use CertificateException in TrustManager?

733 Views Asked by At

I uploaded my app to the play store and I received an email from Google developer that I have to modify my sentences in the https code. I am doing a data submission over https using the TrustManager function. I have a valid ssl certificate in my url and everything works perfectly. But I have a deadline to modify and add a CertificateException to the code.

Google send me:

TrustManager

You can find more information about TrustManager in this Google Help Center article.

HostnameVerifier

Your app(s) are using an unsafe implementation of the HostnameVerifier interface. You can find more information about how resolve the issue in this Google Help Center article.

And this is my code:

public class HttpsTrustManager implements X509TrustManager{

    private static TrustManager[] trustManagers;
    private static final X509Certificate[] _AcceptedIssuers = new X509Certificate[]{};
    private X509Certificate[] x509Certificates;

    @Override
    public void checkClientTrusted(

            java.security.cert.X509Certificate[] x509Certificates, String s)
            throws CertificateException {

    }

    @Override
    public void checkServerTrusted(
            java.security.cert.X509Certificate[] x509Certificates, String s)
            throws 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 e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }

        HttpsURLConnection.setDefaultSSLSocketFactory(context
                .getSocketFactory());
    }
}

I hope you can help me. Thank you.

1

There are 1 best solutions below

0
On

well in your code, you just trust everything.which is not safe. as google said, you should judge the certificate and raise an Exception. like this,

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

        // do some check here if the x509Certificates not valid just raise an CertificateException exception.

        // this will check the certificate          
        if(!checkTheHostName(x509Certificates[0]){
            throw new CertificateException("the certificate is invalid ...");
        }
}


private boolean checkTheHostName(Certificate certificate,String hostName){
    return OkHostnameVerifier.INSTANCE.verify("www.yourhostname.com",certificate)
}

the OkHostnameVerifier's code, just in 
https://android.googlesource.com/platform/external/okhttp/+/e82a796/src/main/java/com/squareup/okhttp/internal/tls/OkHostnameVerifier.java

and the code

 @Override
            public boolean verify(String hostName, SSLSession session) {
                // here you should check the hostName, through session
                // do not just return true here, cause it's not safe. like man-in-middle-attack
               Certificate[] certificates = session.getPeerCertificates();
               return verify(host, (X509Certificate) certificates[0]);
    
            }