2016-07-11 2 views
2

Недавно я сделал самостоятельно опалены сертификат на веб-сервере Apache с помощью этого учебника:андроида самостоятельно подписанный сертификат не будет работать

http://theheat.dk/blog/?p=1023&cpage=1

веб-службы требуют сертификат, чтобы открыть. в браузере все идет хорошо. Я импортировал сертификаты, и сайт откроется.

Я сделал файл BKS от rootCA.crt, client.crt, winter fall.crt, но никто не работает.
В Android я

SSL3_GET_CLIENT_CERTIFICATE: равный не возвращал сертификат Нет ЦС известный сервер для проверки?

сообщение об ошибке в журнале apache.

Кажется, моя проблема заключается в комбинации сертификатов для отправки на сервер! в браузере я использую клиент и rootCA, как я могу объединить их для отправки на веб-сервер?

Мой код:

try { 
     DefaultHttpClient httpclient = new MyHttpClient(getApplicationContext()); 
     HttpGet get = new HttpGet("https://xxx.xxx.xxx.xxx/index.php"); 

     try { 
      HttpResponse response = httpclient.execute(get); 
     } catch (ClientProtocolException e) { 
      System.out.println(e.getMessage()); 
     } catch (IOException e) { 
      System.out.println(e.getMessage()); 
     } 
     return "OK"; 


    } catch (Exception err) { 
     return "Err"; 
    } 

И

public class MyHttpClient extends DefaultHttpClient { 

final Context context; 

public MyHttpClient(Context context) { 
    this.context = context; 
} 

@Override 
protected ClientConnectionManager createClientConnectionManager() { 
    SchemeRegistry registry = new SchemeRegistry(); 
    // Register for port 443 our SSLSocketFactory with our keystore 
    // to the ConnectionManager 
    registry.register(new Scheme("https", newSslSocketFactory(), 443)); 
    return new SingleClientConnManager(getParams(), registry); 
} 

private SSLSocketFactory newSslSocketFactory() { 
    try { 
     // Get an instance of the Bouncy Castle KeyStore format 
     KeyStore trusted = KeyStore.getInstance("BKS"); 
     // Get the raw resource, which contains the keystore with 
     // your trusted certificates (root and any intermediate certs) 
     InputStream in = context.getResources().openRawResource(R.raw.comb); 
     try { 
      // Initialize the keystore with the provided trusted certificates 
      // Also provide the password of the keystore 
      trusted.load(in, "mysecret".toCharArray()); 
     } finally { 
      in.close(); 
     } 

     // Pass the keystore to the SSLSocketFactory. The factory is responsible 
     // for the verification of the server certificate. 
     SSLSocketFactory sf = new SSLSocketFactory(trusted); 
     // Hostname verification from certificate 
     // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e506 
     //sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 
     HttpsURLConnection.setDefaultHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 

     return sf; 
    } catch (Exception e) { 
     throw new AssertionError(e); 
    } 
} 

Ваш помогает очень ценна!

+0

Отправьте свой код. –

+0

мой код прилагается – Mehdi

+0

В какой версии Android вы столкнулись с этой проблемой? –

ответ

1

Использовать ниже данный изготовленный под заказ SSLSocketFactory класс.

public class AndroidSSLSocketFactory extends SSLSocketFactory { 
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(
      "X509"); 
    public AndroidSSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { 
     super(truststore); 
     tmf.init(truststore); 
     TrustManager[] trustManagers = tmf.getTrustManagers(); 
     final X509TrustManager origTrustmanager = (X509TrustManager)trustManagers[0]; 
     TrustManager tm = new X509TrustManager() { 
      public java.security.cert.X509Certificate[] getAcceptedIssuers() { 
       return origTrustmanager.getAcceptedIssuers(); 
      } 

      @Override 
      public void checkClientTrusted(
        java.security.cert.X509Certificate[] chain, String authType) 
        throws CertificateException { 
       origTrustmanager.checkClientTrusted(chain, authType); 
      } 

      @Override 
      public void checkServerTrusted(
        java.security.cert.X509Certificate[] chain, String authType) 
        throws CertificateException { 
       origTrustmanager.checkServerTrusted(chain, authType); 
      } 
     }; 
     SSLContext sslContext = SSLContext.getInstance("TLS"); 
     sslContext.init(null, new TrustManager[]{tm}, null); 
    } 
} 

Этот класс управляет безопасностью транспортного уровня между сервером и Android через сертификат X509.

Используйте его в своем методе newSslSocketFactory(). Заменить

SSLSocketFactory sf = new SSLSocketFactory(trusted);

С

SSLSocketFactory sf = new AndroidSSLSocketFactory(trusted); 

Надеется, что это поможет вам.

информация: -HttpClient осуждается от Android 6.0, вы должны использовать вместо HttpURLConnection. Link.

Update 1: - По this ссылке для того, чтобы работать с самоподписанным сертификатом Вы можете создать свой собственный TrustManager. Поэтому внесите изменения в код TrustManager. Это может помочь будущим пользователям.

+0

Нет. не изменил ничего – Mehdi

+0

@Igor Ganapolsky Спасибо, что привлек мое внимание к этому, я просто возвращаю null из getAcceptedIssuers(), поскольку он заставит TrustManager доверять всем сертификатам. Поскольку он не работал для Mehdi, я скоро обновлю свой ответ. –

+0

Я обновил свой ответ. –

Смежные вопросы