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?
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
).
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);
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);
}