2016-11-18 3 views
3

У меня был этот ниже код в моем приложении -Ваше приложение использует небезопасную реализацию интерфейса X509TrustManager с клиентом Apache HTTP

public class MySSLSocketFactory extends SSLSocketFactory { 
    SSLContext sslContext = SSLContext.getInstance("TLS"); 

    public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { 
     super(truststore); 

     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; 
      } 
     }; 

     sslContext.init(null, new TrustManager[] { tm }, null); 
    } 

    @Override 
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException { 
     return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose); 
    } 

    @Override 
    public Socket createSocket() throws IOException { 
     return sslContext.getSocketFactory().createSocket(); 
    } 


public static HttpClient getNewHttpClient() { 
    try { 
     KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
     trustStore.load(null, null); 

     SSLSocketFactory sf = new MySSLSocketFactory(trustStore); 
     sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 

     HttpParams params = new BasicHttpParams(); 


     HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 
     HttpProtocolParams.setContentCharset(params, HTTP.UTF_8); 

     SchemeRegistry registry = new SchemeRegistry(); 
     registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); 
     registry.register(new Scheme("https", sf, 443)); 

     ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry); 

     return new DefaultHttpClient(ccm, params); 
    } catch (Exception e) { 
     return new DefaultHttpClient(); 
    } 
} 


} 

Но, Google Play магазин отклонил мое приложение для этого. Указание причины -

Ваше приложение использует небезопасную реализацию интерфейса X509TrustManager с клиентом Apache HTTP, в результате безопасности уязвимости. Пожалуйста, см. Статью this Google Help Center для получения дополнительной информации, , включая крайний срок для устранения уязвимости.

Итак, чтобы избавиться от этого. Я попытался загрузки сертификата с веб-сайта, и попытался использовать его через этот код ниже, instead of the above one -

public class MyHttpClient extends DefaultHttpClient { 

    private static Context context; 

    public static void setContext(Context context) { 
     MyHttpClient.context = context; 
    } 

    public MyHttpClient(HttpParams params) { 
     super(params); 
    } 
    public MyHttpClient(Context ctx) { 
     context = ctx; 

    } 
    public MyHttpClient(ClientConnectionManager httpConnectionManager, HttpParams params) { 
     super(httpConnectionManager, params); 
    } 

    @Override 
    protected ClientConnectionManager createClientConnectionManager() { 
     SchemeRegistry registry = new SchemeRegistry(); 
     registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); 
     // Register for port 443 our SSLSocketFactory with our keystore 
     // to the ConnectionManager 
     try { 
      registry.register(new Scheme("https", getSSLSocketFactory(), 443)); 
     } catch (CertificateException e) { 
      e.printStackTrace(); 
     } catch (KeyStoreException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } catch (NoSuchAlgorithmException e) { 
      e.printStackTrace(); 
     } catch (KeyManagementException e) { 
      e.printStackTrace(); 
     } catch (UnrecoverableKeyException e) { 
      e.printStackTrace(); 
     } 
     return new SingleClientConnManager(getParams(), registry); 
    } 

    public static org.apache.http.conn.ssl.SSLSocketFactory getSSLSocketFactory() 
      throws CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException, KeyManagementException, UnrecoverableKeyException { 
     CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
     InputStream caInput = context.getResources().openRawResource(R.raw.dummy_certificate); // this cert file stored in \app\src\main\res\raw folder path 

     Certificate ca = cf.generateCertificate(caInput); 
     caInput.close(); 

     KeyStore keyStore = KeyStore.getInstance("BKS"); 
     keyStore.load(null, null); 
     keyStore.setCertificateEntry("ca", ca); 

     String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); 
     TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); 
     tmf.init(keyStore); 

      getWrappedTrustManagers(tmf.getTrustManagers()); 

     org.apache.http.conn.ssl.SSLSocketFactory sf=new SSLSocketFactory(keyStore); 
     sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER); 

     return sf; 
    } 




    public static TrustManager[] getWrappedTrustManagers(TrustManager[] trustManagers) { 
     final X509TrustManager originalTrustManager = (X509TrustManager) trustManagers[0]; 
     return new TrustManager[]{ 
       new X509TrustManager() { 
        public X509Certificate[] getAcceptedIssuers() { 
         return originalTrustManager.getAcceptedIssuers(); 
        } 

        public void checkClientTrusted(X509Certificate[] certs, String authType) { 
         try { 
          if (certs != null && certs.length > 0) { 
           certs[0].checkValidity(); 
          } else { 
           originalTrustManager.checkClientTrusted(certs, authType); 
          } 
         } catch (CertificateException e) { 
          Log.w("checkClientTrusted", e.toString()); 
         } 
        } 

        public void checkServerTrusted(X509Certificate[] certs, String authType) { 
         try { 
          if (certs != null && certs.length > 0) { 
           certs[0].checkValidity(); 
          } else { 
           originalTrustManager.checkServerTrusted(certs, authType); 
          } 
         } catch (CertificateException e) { 
          Log.w("checkServerTrusted", e.toString()); 
         } 
        } 
       } 
     }; 
    } 
    } 

и назвал ее -

DefaultHttpClient client = new MyHttpClient(App.getContext()); 

Но теперь получаю исключение -

javax.net.ssl.SSLPeerUnverifiedException: No peer certificate 
at com.android.org.conscrypt.SSLNullSession.getPeerCertificates(SSLNullSession.java:104) 
[gralloc_lock]: new usage 0x933 
at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:93) 
at org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:388) 
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:165) 
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164) 
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119) 
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360) 
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555) 
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487) 
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465) 
at com.example.http.HTTPPost.executeRequest(HTTPPost.java:336) 
at com.example.http.HTTPPost.callHttpRequest(HTTPPost.java:301) 
11-17 18:19:57.788 7548-7548/com.savelife I/brcm-gr: [gralloc_lock]: new usage 0x933 
at com.example.http.HTTPPost.doInBackground(HTTPPost.java:286) 
at com.example.http.HTTPPost.doInBackground(HTTPPost.java:67) 
at android.os.AsyncTask$2.call(AsyncTask.java:288) 
at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
at java.lang.Thread.run(Thread.java:818) 

Файл приложения Gradle

apply plugin: 'com.android.application' 
android { 
    compileSdkVersion 22 
    buildToolsVersion '22.0.0' 

    defaultConfig { 
     applicationId "com.example" 
     minSdkVersion 11 
     targetSdkVersion 22 
    } 

    buildTypes { 
     release { 
      minifyEnabled false 
//   proguardFiles getDefaultProguardFile('proguard-android.txt') 
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' 
     } 
    } 
} 
dependencies { 

    compile files('libs/gson-1.7.1.jar') 
    compile files('libs/universal-image-loader-1.9.1.jar') 

    compile files('libs/libGoogleAnalyticsServices.jar') 
    compile 'com.android.support:appcompat-v7:22.2.0' 
    compile 'com.android.support:recyclerview-v7:22.0.+' 
    compile files('libs/volley.jar') 

    compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.2' 
} 

Я не уверен, может быть, виновником являются зависимости в моем файле gradle или в нижних версиях.

Может кто-нибудь сказать, что я делаю неправильно здесь? Я ничего не хочу?

Я нашел много похожих размещенных вопросов, но до сих пор остается без ответа, к несчастью.

+0

попробовать включить HttpClient этот путь: https://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior -apache-клиент-клиент – nandsito

ответ

1

Использование volley lib, вместо HttpClient, работало на меня.

import java.io.File; 
import java.io.IOException; 
import java.io.InputStream; 
import java.net.URL; 
import java.security.KeyManagementException; 
import java.security.KeyStore; 
import java.security.KeyStoreException; 
import java.security.NoSuchAlgorithmException; 
import java.security.cert.Certificate; 
import java.security.cert.CertificateException; 
import java.security.cert.CertificateFactory; 
import java.security.cert.X509Certificate; 
import java.util.UUID; 

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.TrustManagerFactory; 
import javax.net.ssl.X509TrustManager; 


/** 
* Created by mobileappz113 on 17/11/16. 
*/ 
public class OkHttpUrlStack extends HurlStack { 

    private static final int CONNECT_TIMEOUT_MILLIS = 60 * 1000; // 30s 
    private static final int READ_TIMEOUT_MILLIS = 85 * 1000; // 45s 
    // private final OkUrlFactory okUrlFactory; 

    public OkHttpUrlStack(Context mContext) { 
     //this(new OkHttpClient(), mContext); 
    } 




    @Override 
    protected HttpsURLConnection createConnection(URL url) throws IOException { 
     HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url.openConnection(); 
     try { 
      httpsURLConnection.setSSLSocketFactory(getSSLSocketFactory()); 
      httpsURLConnection.setHostnameVerifier(getHostnameVerifier()); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return httpsURLConnection; 
    } 

    /* static Cache getCache(Context mContext) { 
     return new Cache(getCacheDir(mContext), 1024); 
    }*/ 

    public static File getCacheDir(Context mContext) { 
     File outputDir = mContext.getCacheDir(); // context being the Activity pointer 
     File outputFile = null; 
     try { 
      outputFile = File.createTempFile(UUID.randomUUID().toString(), "tmp", outputDir); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return outputFile; 

    } 

    public static HostnameVerifier getHostnameVerifier() { 
     return new HostnameVerifier() { 
      @Override 
      public boolean verify(String hostname, SSLSession session) { 
       //return true; // verify always returns true, which could cause insecure network traffic due to trusting TLS/SSL server certificates for wrong hostnames 
       HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier(); 
//    return hv.verify("localhost", session); 
       return true; 
      } 
     }; 
    } 

    public static javax.net.ssl.SSLSocketFactory getSSLSocketFactory() 
      throws CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException, KeyManagementException { 
     CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
     InputStream caInput = App.getContext().getResources().openRawResource(R.raw.dummy_certificate); // this cert file stored in \app\src\main\res\raw folder path 

     Certificate ca = cf.generateCertificate(caInput); 
     caInput.close(); 

     KeyStore keyStore = KeyStore.getInstance("BKS"); 
     keyStore.load(null, null); 
     keyStore.setCertificateEntry("ca", ca); 

     String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); 
     TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); 
     tmf.init(keyStore); 

     TrustManager[] wrappedTrustManagers = getWrappedTrustManagers(tmf.getTrustManagers()); 

     SSLContext sslContext = SSLContext.getInstance("TLS"); 
     sslContext.init(null, wrappedTrustManagers, null); 

     return sslContext.getSocketFactory(); 
    } 

    public static TrustManager[] getWrappedTrustManagers(TrustManager[] trustManagers) { 
     final X509TrustManager originalTrustManager = (X509TrustManager) trustManagers[0]; 
     return new TrustManager[]{ 
       new X509TrustManager() { 
        public X509Certificate[] getAcceptedIssuers() { 
         return originalTrustManager.getAcceptedIssuers(); 
        } 

        public void checkClientTrusted(X509Certificate[] certs, String authType) { 
         try { 
          if (certs != null && certs.length > 0) { 
           certs[0].checkValidity(); 
          } else { 
           originalTrustManager.checkClientTrusted(certs, authType); 
          } 
         } catch (CertificateException e) { 
          Log.w("checkClientTrusted", e.toString()); 
         } 
        } 

        public void checkServerTrusted(X509Certificate[] certs, String authType) { 
         try { 
          if (certs != null && certs.length > 0) { 
           certs[0].checkValidity(); 
          } else { 
           originalTrustManager.checkServerTrusted(certs, authType); 
          } 
         } catch (CertificateException e) { 
          Log.w("checkServerTrusted", e.toString()); 
         } 
        } 
       } 
     }; 
    } 
} 

И называя это нравится -

public RequestQueue getRequestQueue() { 
     if (mRequestQueue == null) { 
      OkHttpUrlStack okHttpUrlStack = new OkHttpUrlStack(getApplicationContext()); 
      mRequestQueue = Volley.newRequestQueue(getApplicationContext(), okHttpUrlStack); 
     } 

     return mRequestQueue; 
    } 
Смежные вопросы