【问题标题】:Now that SSLSocketFactory is deprecated on Android, what would be the best way to handle Client Certificate Authentication?现在 SSLSocketFactory 在 Android 上已被弃用,处理客户端证书身份验证的最佳方法是什么?
【发布时间】:2015-09-09 05:10:19
【问题描述】:

我正在开发一个需要客户端证书身份验证的 Android 应用程序(使用 PKCS 12 文件)。 在所有 apache.http.* 被弃用之后,我们已经开始对网络层进行相当大的重构工作,我们决定使用 OkHttp 作为替代品,到目前为止我非常喜欢。

但是,我还没有找到任何其他方法来处理客户端证书身份验证,而不使用 SSLSocketFactory、OkHttp 或其他任何东西。那么在这种特殊情况下,最好的行动方案是什么? OkHttp 是否有另一种方式来处理这种身份验证?

【问题讨论】:

  • SSLSocketFactory 未弃用,无论是在 current shipping versions of Android 还是在 M 开发者预览版中。
  • 天哪,你说得对,我从来没有意识到 SSLSocketFactory 有 2 个类! org.apache.http.conn.ssl.SSLSocketFactory 已被弃用,但 javax.net.ssl.SSLSocketFactory 不是!非常感谢您的启发。
  • 相反,我没有意识到 HttpClient 有自己的 SSLSocketFactory 类。 :-)

标签: android ssl okhttp pkcs#12 sslsocketfactory


【解决方案1】:

如果您使用的是 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);

【讨论】:

  • 谢谢,只需添加信任管理器即可删除已弃用的警告。
  • 我仍然得到 SSLHandshakeException: connection closed by peer
  • 我不是 NTLM 专家,但您可能需要使用外部库作为 JCIFS。
【解决方案2】:

显然,有两个SSLSocketFactory 类。 HttpClient 有自己的一个,它与 HttpClient 的其余部分一起被弃用。但是,其他所有人都将使用the more conventional javax.net.ssl edition of SSLSocketFactory,它并未被弃用(感谢$DEITY)。

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

    • 信任每个证书和主机名是个坏主意。
    • 安全漏洞!不建议这样做
    猜你喜欢
    • 1970-01-01
    • 2011-03-08
    • 1970-01-01
    • 2017-09-03
    • 1970-01-01
    • 2011-04-09
    • 2013-10-07
    • 2021-02-02
    • 1970-01-01
    相关资源
    最近更新 更多