How to fix unsafe implementation of X509TrustManager in Android app

后端 未结 5 1868
被撕碎了的回忆
被撕碎了的回忆 2020-12-04 13:31

Google has advised that I have an unsafe implementation of the interface X509TrustManager in my Android application and need to change my code as follows:

相关标签:
5条回答
  • 2020-12-04 14:02

    If you encounter this from external library you're using, check if appache libraray is the cause of it.

    For me apache library caused the error : i was using deprecated class - MultipartEntity. This class uses SSLContextBuilder which uses TrustManagerDelegate. TrustManagerDelegate implements X509TrustManager, which cause "unsafe implementation of TrustManager" error when uploading application to google play store.

    The solution is : instead of deprecated MultipartEntity class, use MultipartEntityBuilder.

    For example :

    MultipartEntity httpMultipart = new MultipartEntity();
    String contentType = httpMultipart.getContentType().getValue();
    

    Will be replaced by :

    MultipartEntityBuilder httpMultipart = new MultipartEntityBuilder();
    String contentType = httpMultipart.build().getContentType().getValue();
    
    0 讨论(0)
  • 2020-12-04 14:02

    I have meet this problem.If your code is like that:

     TrustManager tm = new X509TrustManager()  {
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }
    
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }
    
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    };
    

    it will accept all certificate and it is a bad idea,so google send you mail. We can make a change to accept self-signed certificate too. I solved it,here is my question and my solution

    0 讨论(0)
  • 2020-12-04 14:07

    Add the upgraded version of OKttps worked for me crashing in Android 10

    implementation 'com.squareup.okhttp3:okhttp:4.8.0'
    
    0 讨论(0)
  • 2020-12-04 14:14

    I have solved this using the following code:

    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    try {
                        chain[0].checkValidity();
                    } catch (Exception e) {
                        throw new CertificateException("Certificate not valid or trusted.");
                    }
                }
    
    0 讨论(0)
  • If you are using HttpClient then the solution of @Nabeel is very nice, but if you are using HttpsUrlConnection then this code is very nice for that:

    import android.util.Log;
    
    import java.security.SecureRandom;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    
    import javax.net.ssl.HostnameVerifier;
    import javax.net.ssl.HttpsURLConnection;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLSession;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.X509TrustManager;
    
    /**
     * TrustManager that accepts all certificates and hosts.
     * Useful when you want to use HTTPS but you have self-signed certificates.
     * Works with HttpsUrlConnection.
     * Use at your own risk and only for development.
     *
     * @author gotev (Aleksandar Gotev)
     */
    public class AllCertificatesAndHostsTruster implements TrustManager, X509TrustManager {
    
        @Override
        public final void checkClientTrusted(final X509Certificate[] xcs, final String string)
                throws CertificateException {
        }
    
        @Override
        public final void checkServerTrusted(final X509Certificate[] xcs, final String string)
                throws CertificateException {
        }
    
        @Override
        public final X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    
        /**
         * Gets an {@link SSLContext} which trusts all certificates.
         * @return {@link SSLContext}
         */
        public static SSLContext getSSLContext() {
            final TrustManager[] trustAllCerts =
                    new TrustManager[] {new AllCertificatesAndHostsTruster()};
    
            try {
                final SSLContext context = SSLContext.getInstance("SSL");
                context.init(null, trustAllCerts, new SecureRandom());
                return context;
    
            } catch (Exception exc) {
                Log.e("CertHostTruster", "Unable to initialize the Trust Manager to trust all the "
                        + "SSL certificates and HTTPS hosts.", exc);
                return null;
            }
        }
    
        /**
         * Creates an hostname verifier which accepts all hosts.
         * @return {@link HostnameVerifier}
         */
        public static HostnameVerifier getAllHostnamesVerifier() {
            return new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            };
        }
    
        /**
         * Call this method once before all your network calls
         * to accept all the self-signed certificates in HTTPS connections.
         */
        public static void apply() {
            final TrustManager[] trustAllCerts =
                    new TrustManager[] {new AllCertificatesAndHostsTruster()};
    
            try {
                final SSLContext context = SSLContext.getInstance("SSL");
                context.init(null, trustAllCerts, new SecureRandom());
                HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
                HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
    
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                });
    
            } catch (Exception exc) {
                Log.e("CertHostTruster", "Unable to initialize the Trust Manager to trust all the "
                        + "SSL certificates and HTTPS hosts.", exc);
            }
        }
    }
    

    Source: https://gist.github.com/gotev/6784c1303793c6ee9e56

    Then to use self-signed certificates, just invoke:

    AllCertificatesAndHostsTruster.apply();
    

    before any network calls.

    0 讨论(0)
提交回复
热议问题