OkHttp javax.net.ssl.SSLPeerUnverifiedException: Hostname domain.com nicht verifiziert

Lesezeit: 5 Minuten

Ich versuche seit Tagen, das zum Laufen zu bringen. Ich versuche, eine Verbindung zu meinem Server herzustellen https mit einem selbstsignierten Zertifikat. Ich glaube, es gibt keine Seiten oder Beispiele, die ich noch nicht gelesen habe.

Was habe ich getan:

  1. Erstellen Sie den bks-Schlüsselspeicher, indem Sie diesem Tutorial folgen: http://blog.crazybob.org/2010/02/android-trusting-ssl-certificates.html

Es benutzt openssl s_client -connect domain.com:443 um das Zertifikat vom Server zu erhalten. Erstellt dann einen bks-Keystore mit Hüpfburg.

  1. Lesen des erstellten Keystores aus dem Raw-Ordner, Hinzufügen zu sslfactory und dann zu OkHttpClient. So was:

    public ApiService() {
        mClient = new OkHttpClient();
        mClient.setConnectTimeout(TIMEOUT_SECONDS, TimeUnit.SECONDS);
        mClient.setReadTimeout(TIMEOUT_SECONDS, TimeUnit.SECONDS);
        mClient.setCache(getCache());
        mClient.setCertificatePinner(getPinnedCerts());
        mClient.setSslSocketFactory(getSSL());
    }
    
    protected SSLSocketFactory getSSL() {
        try {
            KeyStore trusted = KeyStore.getInstance("BKS");
            InputStream in = Beadict.getAppContext().getResources().openRawResource(R.raw.mytruststore);
            trusted.load(in, "pwd".toCharArray());
            SSLContext sslContext = SSLContext.getInstance("TLS");
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(trusted);
            sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
            return sslContext.getSocketFactory();
        } catch(Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    public CertificatePinner getPinnedCerts() {
        return new CertificatePinner.Builder()
                .add("domain.com", "sha1/theSha=")
                .build();
    }
    
  2. Dies erzeugt aus irgendeinem Grund immer a SSLPeerUnverifiedException mit oder ohne Keystore. Und mit oder ohne CertificatePinner.

    javax.net.ssl.SSLPeerUnverifiedException: Hostname domain.com not verified: 0         
     W/System.err﹕ certificate: sha1/theSha=
     W/System.err﹕ DN: 1.2.840.113549.1.9.1=#1610696e666f40626561646963742e636f6d,CN=http://domain.com,OU=development,O=domain,L=Valencia,ST=Valencia,C=ES
     W/System.err﹕ subjectAltNames: []
     W/System.err﹕ at com.squareup.okhttp.internal.http.SocketConnector.connectTls(SocketConnector.java:124)
     W/System.err﹕ at com.squareup.okhttp.Connection.connect(Connection.java:143)
     W/System.err﹕ at com.squareup.okhttp.Connection.connectAndSetOwner(Connection.java:185)
     W/System.err﹕ at com.squareup.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:128)
     W/System.err﹕ at com.squareup.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:341)
     W/System.err﹕ at com.squareup.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:330)
     W/System.err﹕ at com.squareup.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
     W/System.err﹕ at com.squareup.okhttp.Call.getResponse(Call.java:273)
     W/System.err﹕ at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:230)
     W/System.err﹕ at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:201)
     W/System.err﹕ at com.squareup.okhttp.Call.execute(Call.java:81)
     ...
    

Was mache ich falsch?

  • Bitte überprüfen Sie, ob Ihr Zertifikat den tatsächlichen Hostnamen und nicht die IP-Adresse enthält (IP-Adressen sollten in Subject Alternative Name Zertifikatsfeld). Wie für HostnameVerifier was true zurückgibt – es macht SSL nutzlos und unsicher (am meisten positiv bewertete Antwort). Auf modernen Androids können Sie Ihr selbstsigniertes Zertifikat problemlos über die Sicherheitseinstellungen installieren.

    – Boris Treuchow

    6. Juli 2016 um 9:59 Uhr


Benutzer-Avatar
qrtLs

Während der Zertifikatsgenerierung wird die subjectAltName muss gesetzt werden, wenn die URI eine IP ist, um nicht durch die Validierung zu fallen.

“In einigen Fällen wird der URI als IP-Adresse und nicht als Hostname angegeben. In diesem Fall muss die iPAddress subjectAltName im Zertifikat vorhanden sein und genau mit der IP im URI übereinstimmen.” RFC (erwähnt von Bas im Kommentar)

Anstatt clientseitig mit zu fummeln HostnameVerifier oder reiussieren Sie das selbstsignierte Zertifikat (über das wir die Kontrolle haben) über:

openssl req \
-newkey rsa:2048 \
-nodes \
-x509 \
-days 36500 -nodes \
-addext "subjectAltName = IP.1:1.2.3.4" \
-keyout /etc/ssl/private/nginx-selfsigned2.key \
-out /etc/ssl/certs/nginx-selfsigned2.crt

Addon, wenn man auf Android auch dem Zertifikat vertrauen muss:

the crt is pem format and can be imported into android via
<?xml version="1.0" encoding="utf-8"?>
    <base-config cleartextTrafficPermitted="false">
        <trust-anchors>
            <certificates src="@raw/nginx_selfsigned2" />
            <certificates src="system" />
        </trust-anchors>
    </base-config>
</network-security-config>

So überprüfen wir, dass das Zertifikat von einer vertrauenswürdigen Quelle stammt. Und zuvor wurde durch die Überprüfung des Hostnamens (über SAN) sichergestellt, dass der Server, mit dem wir sprechen, das richtige Zertifikat für seine IP-Adresse präsentiert.

mehr hier: https://developer.android.com/training/articles/security-config
https://developer.android.com/training/articles/security-ssl.html#SelfSigned

  • was ist die datei (client) in raw?

    – iSrinivasan27

    12. September 2016 um 7:33 Uhr

  • das ist die client.crtDatei, die auf der openssl-Zeile generiert wird.

    – nur_Benutzer

    12. September 2016 um 10:19 Uhr

  • Was ist die client.pem-Datei, die Sie hier verwendet haben? Dieses Skript generiert einige .pem-Dateien. Ist es die Datei chain.pem im Client-Verzeichnis?

    – Chrischan

    22. März 2017 um 1:55 Uhr

  • Sie müssen es als Teil des SSL-Zertifikats erstellen, das Sie für Ihre Verbindung verwenden möchten: security.stackexchange.com/questions/32768/…

    – nur_Benutzer

    22. März 2017 um 7:36 Uhr

  • Ist es sicher, die .crt-Datei als Rohressource in Ihrer apk zu haben?

    – PrashanD

    16. Dezember 2019 um 4:45 Uhr

Bitte überprüfen Sie, ob der CN-Name auf dem Client-Zertifikat zum alternativen Antragstellernamen hinzugefügt wird. Ich hatte das gleiche Problem

  • Vielen Dank, insbesondere für den alternativen Namen des Betreffs muss gesetzt werden, wenn es sich um eine IP-Adresse anstelle eines Hostnamens handelt: „In einigen Fällen wird die URI als IP-Adresse und nicht als Hostname angegeben. In diesem Fall muss die iPAddress subjectAltName im Zertifikat vorhanden sein und genau mit der IP übereinstimmen im URI.” tools.ietf.org/html/rfc2818#section-3.1

    – Bas

    19. Januar 2019 um 13:33 Uhr

Benutzer-Avatar
dkühn

Dieses Problem wird durch die Einstellung gelöst setHostNameVerifier zu okHttpBuilder. Stellen Sie sicher, dass die Verifizierungsmethode wahr zurückgibt.

Probe:

okHttpClient.setHostnameVerifier(new HostnameVerifier() {
    @Override
    public boolean verify(String hostname, SSLSession session) {
        return true;
    }
});

OkHttpClient.Builder builder = new OkHttpClient.Builder();
    builder.hostnameVerifier(new HostnameVerifier() {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    });
OkHttpClient client = builder.build();

  • Vielen Dank, insbesondere für den alternativen Namen des Betreffs muss gesetzt werden, wenn es sich um eine IP-Adresse anstelle eines Hostnamens handelt: „In einigen Fällen wird die URI als IP-Adresse und nicht als Hostname angegeben. In diesem Fall muss die iPAddress subjectAltName im Zertifikat vorhanden sein und genau mit der IP übereinstimmen im URI.” tools.ietf.org/html/rfc2818#section-3.1

    – Bas

    19. Januar 2019 um 13:33 Uhr

Benutzer-Avatar
Pooya Chavoshi

Wenn Sie verwendet werden network_security_config in res/xml zum lösen Cleartext HTTP traffic not permitted und Sie die Domain/IP-Adresse geändert haben, denken Sie daran, dass Sie dies ändern sollten includeSubdomains Wert an die neue Adresse. Das hat bei mir funktioniert.

  <network-security-config>
    <domain-config cleartextTrafficPermitted="true">
      <domain includeSubdomains="true">yourDomain.com</domain>
    </domain-config>
  </network-security-config>

1010490cookie-checkOkHttp javax.net.ssl.SSLPeerUnverifiedException: Hostname domain.com nicht verifiziert

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

Privacy policy