2014-06-24 16 views
6

Ich versuche SNI-Unterstützung mit SSLCertificateSocketFactory.setHostname hinzufügen, Mit Wireshark ich sehe die Kommunikation zwischen Client und SNI-fähigen Server, der CLIENT HALLO geht zum Server (mit dem richtigen Host-Namen), Server antwortet mit Server Hello und sendet Zertifikat an Client, aber nachdem dieser Client nicht sendet Zertifikat und Kommunikation/Handshake stoppt, über openssl Befehl openssl s_client -connect theclient -servername hostname -cert thecertificate alles läuft reibungslos, Handshake erfolgt erfolgreich ..Android HTTPS SNI-Unterstützung mit SSLCertificateSocketFactory

Ich benutze Sockets und auf socket.startHandshake bekomme ich eine Ausnahme: IOException: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: T Rostanker für Zertifizierungspfad nicht gefunden.

  final SSLCertificateSocketFactory sslSocketFactory = (SSLCertificateSocketFactory) SSLCertificateSocketFactory.getDefault(0); 

      socket = (SSLSocket) sslSocketFactory.createSocket(InetAddress.getByName("theserver"), 443); 


      socket.setEnabledProtocols(socket.getSupportedProtocols()); 

      String[] cipherArray = socket.getEnabledCipherSuites(); 
      for(int i = 0; i<cipherArray.length; i++) { 
       Log.e("","Available Cipher:"+cipherArray[i]); 
      } 
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { 
       sslSocketFactory.setHostname(socket, "thehostname"); 
      } else { 
       try { 
        java.lang.reflect.Method setHostnameMethod = socket.getClass().getMethod("setHostname", String.class); 
        setHostnameMethod.invoke(socket, "thehostname"); 
       } catch (Exception e) { 
        Log.w("", "SNI not useable", e); 
       } 
      } 
      socket.setSoTimeout(20000); 
      socket.setUseClientMode(true); 
      Log.i(getClass().toString(), "Connected."); 
      socket.startHandshake(); 
      SSLSession session = socket.getSession(); 
      boolean secured = session.isValid(); 

Die Lösung dieser IOException SSLHANDSHAKEEXCEPTION auf Android-Entwickler ist https://developer.android.com/training/articles/security-ssl.html#CommonProblems:

„Nehmen Sie ein bestimmten CA von einem Inputstream, verwendet es einen Schlüsselspeicher zu erstellen, die dann einen Trustmanager zu erstellen und initialisieren verwendet wird. Ein TrustManager ist das, was das System verwendet, um Zertifikate vom Server zu validieren, und - indem ein Zertifikat von einem KeyStore mit einer oder mehreren CAs erstellt wird - sind dies die einzigen von diesem TrustManager vertrauenswürdigen CAs

Mit dem neuen TrustManager wird das Beispiel initialisiert ein neuer SSLContext, der Ihnen eine SSLSocketFactory zur Verfügung stellt kann die Standard SSLSocketFactory von HttpsURLConnection überschreiben. Auf diese Weise die Verbindung Ihre CAs zur Validierung des Zertifikats verwenden.“

Nun ist der SSL-Kontext liefert SSLSOCKETFACTORY, ich will SSLCertificateSocketFactory (für sethostname-Methode) verwenden Was .. zu tun, ich hoffe, die Frage klar ist, wenn mich nicht lassen wissen oder fühlen Sie sich frei, um mehr klar

+2

Ich bin vor einem ähnliches Problem. Ich werde verfolgen, was hier passiert. Hier ist ein Pastebin von einigen der Codeschnipsel, die ich benutze: http://pastebin.com/K18PwtLa – Derek

Antwort

2

Sie machen die NetCipher Bibliothek verwenden können, eine moderne TLS Konfiguration zu erhalten, wenn die Android mit HttpsURLConnection einschließlich SNI-Unterstützung. NetCipher konfiguriert die HttpsURLConnection Instanz die besten unterstützt TLS-Version, sowie die verwenden Die beste Suite von Verschlüsselungscodes für diese TLS-Version: Fügen Sie sie zuerst Ihrer build.gradle:

0 hinzu
compile 'info.guardianproject.netcipher:netcipher:2.0.0-alpha1' 

Oder Sie laden Sie die netcipher.jar und schließen Sie es direkt in der App. Dann statt Aufruf:

HttpURLConnection connection = (HttpURLConnection) sourceUrl.openConnection(); 

Rufen Sie:

HttpsURLConnection connection = NetCipher.getHttpsURLConnection(sourceUrl); 

Wenn Sie sehen möchten, wie getan, um seinen im Code, schaut TlsOnlySocketFactory

+0

Es ist eine großartige Lösung, hat gearbeitet und mich gerettet. +1 von mir – christian