27

I am working on an Android app that requires Client Certificate Authentication (with PKCS 12 files). Following the deprecation of all that's apache.http.*, we have started a pretty big work of refactoring on our network layer, and we have decided to go with OkHttp as a replacement, and so far I like that very much.

However, I haven't found any other way to handle client certificate auth without using SSLSocketFactory, with OkHttp or anything else for that matter. So what would be the best course of action in this particular case? Is there another way with OkHttp to handle this sort of authentication?

4

3 回答 3

53

如果您使用的是 https,则必须使用有效的证书。在您的开发阶段,您必须信任证书,如何? sslSocketFactory(SSLSocketFactory sslSocketFactory)已弃用并将其替换为sslSocketFactory(SSLSocketFactory sslSocketFactory, X509TrustManager trustManager),您必须更新您的 gradle 文件,下面的代码将帮助您获得信任任何 ssl 证书的受信任的 OkHttpClient。

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);
于 2016-11-29T20:11:47.697 回答
18

显然,有两个SSLSocketFactory班级。HttpClient 有自己的一个,它与 HttpClient 的其余部分一起被弃用。但是,其他所有人都将使用更传统javax.net.ssl的版本SSLSocketFactory,该版本未被弃用(谢谢$DEITY)。

于 2015-06-23T12:48:39.360 回答
1

看这个,我找到了一些解决方案,并且在我这边运行良好。检查我是如何集成的..

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

在此处添加客户端实例的所有属性

. . .

并为 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);
  }
于 2018-11-07T14:42:46.443 回答