web-dev-qa-db-fra.com

Maintenant que SSLSocketFactory est obsolète sur Android, quel serait le meilleur moyen de gérer l'authentification par certificat client?

Je travaille sur une application Android nécessitant une authentification par certificat client (avec les fichiers PKCS 12). Suite à la désapprobation de tout ce qui est Apache.http.*, nous avons commencé un assez gros travail de refactorisation sur notre couche réseau, et nous avons décidé d’utiliser OkHttp en remplacement, et jusqu’à présent, j’aime beaucoup cela.

Cependant, je n'ai trouvé aucun autre moyen de gérer l'authentification du certificat client sans utiliser SSLSocketFactory, avec OkHttp ou quoi que ce soit d'autre. Alors, quel serait le meilleur plan d'action dans ce cas particulier? Existe-t-il un autre moyen avec OkHttp de gérer ce type d'authentification?

15
TheYann

Apparemment, il existe deux classes SSLSocketFactory. HttpClient a son propre, qui est déconseillé avec le reste de HttpClient. Cependant, tout le monde utilisera l'édition plus conventionnelle javax.net.ssl de SSLSocketFactory , qui n'est pas obsolète (merci $DEITY).

14
CommonsWare

si vous utilisez https, vous devez utiliser un certificat valide. Pendant votre phase de développement, vous devez faire confiance au certificat. Comment? sslSocketFactory(SSLSocketFactory sslSocketFactory) est obsolète et remplacé par sslSocketFactory(SSLSocketFactory sslSocketFactory, X509TrustManager trustManager), vous devez mettre à jour votre fichier Gradle Le morceau de code ci-dessous vous aidera à obtenir un OkHttpClient fiable qui fait confiance tout certificat de ssl.

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

Regardez, je trouve une solution et à mes côtés, le travail est bon. Vérifiez comment j'ai intégré ..

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

ajoutez ici toutes les propriétés de l'instance client

...

et ajoutez ces lignes de code pour sslSocketFactory:

 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