HTTPS-Verbindung Android

Lesezeit: 8 Minuten

HTTPS Verbindung Android
Sam97305421562

Ich mache einen https-Post und erhalte eine Ausnahme von SSL-Ausnahme Nicht vertrauenswürdiges Serverzertifikat. Wenn ich normales http mache, funktioniert es einwandfrei. Muss ich das Serverzertifikat irgendwie akzeptieren?

Das ist, was ich tue. Das Zertifikat wird einfach nicht mehr überprüft.

// always verify the host - dont check for certificate
final static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
    public boolean verify(String hostname, SSLSession session) {
        return true;
    }
};

/**
 * Trust every server - dont check for any certificate
 */
private static void trustAllHosts() {
    // Create a trust manager that does not validate certificate chains
    TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return new java.security.cert.X509Certificate[] {};
        }

        public void checkClientTrusted(X509Certificate[] chain,
                String authType) throws CertificateException {
        }

        public void checkServerTrusted(X509Certificate[] chain,
                String authType) throws CertificateException {
        }
    } };

    // Install the all-trusting trust manager
    try {
        SSLContext sc = SSLContext.getInstance("TLS");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection
                .setDefaultSSLSocketFactory(sc.getSocketFactory());
    } catch (Exception e) {
        e.printStackTrace();
    }
}

und

    HttpURLConnection http = null;

    if (url.getProtocol().toLowerCase().equals("https")) {
        trustAllHosts();
        HttpsURLConnection https = (HttpsURLConnection) url.openConnection();
        https.setHostnameVerifier(DO_NOT_VERIFY);
        http = https;
    } else {
        http = (HttpURLConnection) url.openConnection();
    }

  • Das sieht gut aus! Ich verwende jedoch WebView und muss mich nur zu Testzwecken mit einem https-Server verbinden. (Der Client kann keinen mit einem passenden FQDN bereitstellen und auch nicht auf http testen.) Gibt es eine Möglichkeit, dies bei der Verwendung von WebView anzugehen? Muss ich diesen Code einfach in die Aktivität einfügen, in der sich die WebView befindet, und “es funktioniert einfach?” (Verdacht nicht … ??)

    – Joe D’Andrea

    2. September 2010 um 21:13 Uhr

  • Ich versuche, diese Lösung Schritt für Schritt zu verwenden, und erhalte eine solche Ausnahme: 07-25 12:35:25.941: WARN/System.err(24383): java.lang.ClassCastException: org.apache.harmony.luni .internal.net.www.protocol.http.HttpURLConnectionImpl an Ort und Stelle, wo ich versuche, eine Verbindung zu öffnen … irgendeine Idee warum??

    – Robert

    25. Juli 2011 um 10:39 Uhr

  • Hey, ich habe es so gemacht, wie du es vorgeschlagen hast, aber ich bekomme die Ausnahme wie javax.net.ssl.SSLException: Received fatal alert: bad_record_mac . Ich habe auch versucht zu ersetzen TLS mit SSL aber es half nichts. Bitte helfen Sie mir, danke

    – devsri

    22. Februar 2012 um 17:24 Uhr

  • Während dies während der Entwicklungsphase gut ist, sollten Sie sich der Tatsache bewusst sein, dass dies jedem ermöglicht, Ihre sichere Verbindung zu MITM, indem er ein zufälliges SSL-Zertifikat fälscht, wodurch Ihre Verbindung nicht mehr sicher ist. Schau mal rein diese Frage um zu sehen, dass es richtig gemacht wurde, Hier um zu sehen, wie man ein Zertifikat erhält, und schließlich Das um zu erfahren, wie Sie es dem Schlüsselspeicher hinzufügen.

    – Zimt

    1. März 2012 um 7:44 Uhr


  • Sie sollten diesen Code nicht empfehlen oder posten. Es ist radikal unsicher. Sie sollten das eigentliche Problem lösen.

    – Benutzer207421

    12. März 2016 um 2:14 Uhr

1646338032 175 HTTPS Verbindung Android
Nate

Ich vermute, aber wenn Sie möchten, dass ein tatsächlicher Handshake stattfindet, müssen Sie Android Ihr Zertifikat mitteilen. Wenn Sie einfach akzeptieren wollen, egal was, dann verwenden Sie diesen Pseudo-Code, um mit dem Apache HTTP-Client das zu bekommen, was Sie brauchen:

SchemeRegistry schemeRegistry = new SchemeRegistry ();

schemeRegistry.register (new Scheme ("http",
    PlainSocketFactory.getSocketFactory (), 80));
schemeRegistry.register (new Scheme ("https",
    new CustomSSLSocketFactory (), 443));

ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager (
    params, schemeRegistry);


return new DefaultHttpClient (cm, params);

Benutzerdefinierte SSLSocketFactory:

public class CustomSSLSocketFactory extends org.apache.http.conn.ssl.SSLSocketFactory
{
private SSLSocketFactory FACTORY = HttpsURLConnection.getDefaultSSLSocketFactory ();

public CustomSSLSocketFactory ()
    {
    super(null);
    try
        {
        SSLContext context = SSLContext.getInstance ("TLS");
        TrustManager[] tm = new TrustManager[] { new FullX509TrustManager () };
        context.init (null, tm, new SecureRandom ());

        FACTORY = context.getSocketFactory ();
        }
    catch (Exception e)
        {
        e.printStackTrace();
        }
    }

public Socket createSocket() throws IOException
{
    return FACTORY.createSocket();
}

 // TODO: add other methods like createSocket() and getDefaultCipherSuites().
 // Hint: they all just make a call to member FACTORY 
}

FullX509TrustManager ist eine Klasse, die javax.net.ssl.X509TrustManager implementiert, aber keine der Methoden führt tatsächlich irgendeine Arbeit aus, holen Sie sich ein Beispiel Hier.

Viel Glück!

  • Warum gibt es die Variable FACTORY?

    – Codevalley

    27. September 2010 um 12:18 Uhr

  • Rückgabe FACTORY.createSocket(); hat ein Problem. Der erstellte Socket gibt bei execute() eine null Pointer-Ausnahme aus. Außerdem ist mir aufgefallen, dass es 2 SocketFactory-Klassen gibt. 1. org.apache.http.conn.ssl.SSLSocketFactory und 2. javax.net.ssl.SSLSocketFactory

    – Codevalley

    28. September 2010 um 7:42 Uhr


  • Hallo Nate, das sieht nach etwas Hilfreichem für meine Situation aus. Aber ich habe einige Probleme mit der Erstellung der CustomSSLSocketFactory. Welche Klasse soll es erweitern? Oder welche Schnittstelle soll es implementieren? Ich habe experimentiert mit: javax.net.SocketFactory, javax.net.ssl.SSLSocketFactory, org.apache.http.conn.scheme.SocketFactory, die alle die Implementierung anderer Methoden erzwingen … Also, im Allgemeinen, was werden die Namespaces der Klassen in Ihrem Code verwendet? Danke. 🙂

    – Cephron

    18. März 2011 um 18:23 Uhr


  • Funktioniert bei mir nicht, gibt mir den gleichen Fehler “Nicht vertrauenswürdiges Serverzertifikat”.

    – Omar Rehmann

    8. Juni 2011 um 12:57 Uhr

  • wie bekomme ich diese klasse FullX509TrustManager

    – RajaReddy PolamReddy

    27. August 2012 um 10:59 Uhr

Beim Versuch, diese Frage zu beantworten, fand ich ein besseres Tutorial. Damit müssen Sie die Zertifikatsprüfung nicht kompromittieren.

http://blog.crazybob.org/2010/02/android-trusting-ssl-certificates.html

*Ich habe das nicht geschrieben, aber danke an Bob Lee für die Arbeit

  • Dies ist die perfekte Antwort. Ich habe einen Update-Beitrag erstellt, der zeigt, wie mit nicht aufgelisteten Zertifizierungsstellen umgegangen wird, da ich einen PeerCertificate-Fehler erhalten habe. Sehen Sie es hier: blog.donnfelker.com/2011/06/13/…

    – Don Felker

    13. Juni 2011 um 21:09 Uhr

1646338032 213 HTTPS Verbindung Android
Saxophon

Sie können sich auch meinen Blogartikel ansehen, der Crazybobs sehr ähnlich ist.

Diese Lösung beeinträchtigt auch nicht die Zertifikatsprüfung und erklärt, wie Sie die vertrauenswürdigen Zertifikate in Ihrem eigenen Schlüsselspeicher hinzufügen.

http://blog.antoine.li/index.php/2010/10/android-trusting-ssl-certificates/

HTTPS Verbindung Android
Rohit Mandiwal

http://madurangasblogs.blogspot.in/2013/08/avoiding-javaxnetsslsslpeerunverifiedex.html

Mit freundlicher Genehmigung von Maduranga

Wenn Sie eine Anwendung entwickeln, die https verwendet, verfügt Ihr Testserver über kein gültiges SSL-Zertifikat. Oder manchmal verwendet die Website ein selbstsigniertes Zertifikat oder die Website verwendet ein kostenloses SSL-Zertifikat. Wenn Sie also versuchen, sich mit Apache mit dem Server zu verbinden HttpClient, erhalten Sie eine Ausnahme, die besagt, dass der “Peer nicht authentifiziert” ist. Obwohl es keine gute Praxis ist, allen Zertifikaten in einer Produktionssoftware zu vertrauen, müssen Sie dies je nach Situation möglicherweise tun. Diese Lösung behebt die durch „Peer nicht authentifiziert“ verursachte Ausnahme.

Aber bevor wir zur Lösung kommen, muss ich Sie warnen, dass dies keine gute Idee für eine Produktionsanwendung ist. Dies verstößt gegen den Zweck der Verwendung eines Sicherheitszertifikats. Verwenden Sie diese Lösung also nicht, es sei denn, Sie haben einen triftigen Grund oder wenn Sie sicher sind, dass dies kein Problem verursacht.

Normalerweise erstellen Sie eine HttpClient so was.

HttpClient httpclient = new DefaultHttpClient();

Aber Sie müssen die Art und Weise ändern, wie Sie den HttpClient erstellen.

Zuerst müssen Sie eine Klassenerweiterung erstellen org.apache.http.conn.ssl.SSLSocketFactory.

import org.apache.http.conn.ssl.SSLSocketFactory;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

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

Erstellen Sie dann eine Methode wie diese.

public 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();
     }
}

Dann kannst du die erstellen HttpClient.

HttpClient httpclient = getNewHttpClient();

Wenn Sie versuchen, eine Post-Anforderung an eine Anmeldeseite zu senden, würde der Rest des Codes so aussehen.

private URI url = new URI("url of the action of the form");
HttpPost httppost =  new HttpPost(url);
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();  
nameValuePairs.add(new BasicNameValuePair("username", "user"));  
nameValuePairs.add(new BasicNameValuePair("password", "password"));
try {
    httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
    HttpResponse response = httpclient.execute(httppost);
    HttpEntity entity = response.getEntity();
    InputStream is = entity.getContent();
} catch (UnsupportedEncodingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (ClientProtocolException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

Sie erhalten die HTML-Seite zum InputStream. Dann können Sie mit der zurückgegebenen HTML-Seite machen, was Sie wollen.

Aber hier werden Sie auf ein Problem stoßen. Wenn Sie eine Sitzung mithilfe von Cookies verwalten möchten, können Sie dies mit dieser Methode nicht tun. Wenn Sie die Cookies erhalten möchten, müssen Sie dies über einen Browser tun. Nur dann erhalten Sie Cookies.

1646338034 4 HTTPS Verbindung Android
Juan Sanchez

Wenn Sie ein StartSSL- oder Thawte-Zertifikat verwenden, schlägt es für Froyo und ältere Versionen fehl. Sie können eine verwenden CAcert-Repository der neueren Version anstatt jedem Zertifikat zu vertrauen.

1646338035 144 HTTPS Verbindung Android
Gemeinschaft

Keines davon hat bei mir funktioniert (verschlimmert durch die Thawte-Bug auch). Schließlich habe ich es mit der selbstsignierten SSL-Akzeptanz auf Android behoben und die benutzerdefinierte SSL-Verarbeitung funktionierte nicht mehr auf Android 2.2 FroYo

926970cookie-checkHTTPS-Verbindung Android

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy