wake-up-neo.com

Nun, da SSLSocketFactory auf Android veraltet ist, was wäre der beste Weg, um die Client-Zertifikat-Authentifizierung zu handhaben?

Ich arbeite an einer Android-App, für die die Authentifizierung des Clientzertifikats erforderlich ist (mit PKCS 12-Dateien). Nach der Abwertung von allem, was Apache.http.* ist, haben wir mit der Umgestaltung unserer Netzwerkschicht begonnen, und wir haben uns für OkHttp als Ersatz entschieden, und das gefällt mir sehr gut.

Ich habe jedoch keine andere Möglichkeit gefunden, mit Client-Zertifikatsauthentifizierung zu arbeiten, ohne SSLSocketFactory, OkHttp oder irgendetwas anderes zu verwenden. Was wäre also in diesem speziellen Fall die beste Vorgehensweise? Gibt es eine andere Möglichkeit mit OkHttp, um diese Art der Authentifizierung zu handhaben?

15
TheYann

Anscheinend gibt es zwei SSLSocketFactory-Klassen. HttpClient hat einen eigenen, der zusammen mit dem Rest von HttpClient nicht mehr verwendet wird. Alle anderen werden jedoch die konventionellere javax.net.ssl-Edition von SSLSocketFactory verwenden, die nicht veraltet ist (danke $DEITY).

14
CommonsWare

wenn Sie https verwenden, müssen Sie ein gültiges Zertifikat verwenden. Während Ihrer Entwicklungsphase müssen Sie dem Zertifikat vertrauen. Wie? sslSocketFactory(SSLSocketFactory sslSocketFactory) ist veraltet und wird durch sslSocketFactory(SSLSocketFactory sslSocketFactory, X509TrustManager trustManager) ersetzt. Sie müssen Ihre Abschlussdatei .__ irgendein SSL-Zertifikat.

TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
    throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
}
X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new TrustManager[] { trustManager }, null);
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
OkHttpClient client = new OkHttpClient.Builder().sslSocketFactory(sslSocketFactory, trustManager);
29
user2167877

Schau mal, ich finde eine Lösung und in meiner Seite ist die Arbeit gut. Überprüfen Sie, wie ich integriert habe ..

OkHttpClient.Builder client = new OkHttpClient.Builder ();

fügen Sie hier alle Eigenschaften für die Clientinstanz hinzu

...

und fügen Sie diese Codezeile für sslSocketFactory hinzu:

 try {
        // Create a trust manager that does not validate certificate chains
        final TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(Java.security.cert.X509Certificate[] chain, String authType) {
                    }

                    @Override
                    public void checkServerTrusted(Java.security.cert.X509Certificate[] chain, String authType) {
                    }

                    @Override
                    public Java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return new Java.security.cert.X509Certificate[]{};
                    }
                }
        };

        // Install the all-trusting trust manager
        final SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, trustAllCerts, new Java.security.SecureRandom());

        // Create an ssl socket factory with our all-trusting manager
        final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

        client.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
        client.hostnameVerifier((hostname, session) -> true);
    } catch (Exception e) {
        throw new RuntimeException(e);
  }
0
Krste Moskov