android - 使用 okHttp 信任所有证书

标签 android ssl okhttp android-networking

出于测试目的,我正在尝试向我的 okHttp 客户端添加一个套接字工厂,它在设置代理时信任所有内容。这已经做了很多次了,但是我的信任套接字工厂的实现似乎缺少了一些东西:

class TrustEveryoneManager implements X509TrustManager {
    @Override
    public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { }

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

    @Override
    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
        return null;
    }
}
OkHttpClient client = new OkHttpClient();

final InetAddress ipAddress = InetAddress.getByName("XX.XXX.XXX.XXX"); // some IP
client.setProxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(ipAddress, 8888)));

SSLContext sslContext = SSLContext.getInstance("TLS");
TrustManager[] trustManagers = new TrustManager[]{new TrustEveryoneManager()};
sslContext.init(null, trustManagers, null);
client.setSslSocketFactory(sslContext.getSocketFactory);

我的应用程序没有发送任何请求,也没有记录任何异常,因此它似乎在 okHttp 中静默失败。经过进一步调查,当强制握手时,okHttp 的 Connection.upgradeToTls() 似乎有一个异常被吞没。我得到的异常是:javax.net.ssl.SSLException: SSL 握手终止:ssl=0x74b522b0: SSL_ERROR_ZERO_RETURN 发生。你不应该看到这个。

以下代码生成一个 SSLContext,它在创建一个不抛出任何异常的 SSLSocketFactory 时就像一个魅力:

protected SSLContext getTrustingSslContext() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
    final SSLContextBuilder trustingSSLContextBuilder = SSLContexts.custom()
            .loadTrustMaterial(null, new TrustStrategy() {
                @Override
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    return true; // Accepts any ssl cert whether valid or not.
                }
            });
    return trustingSSLContextBuilder.build();
}

问题是我试图从我的应用程序中完全删除所有 Apache HttpClient 依赖项。使用 Apache HttpClient 生成 SSLContext 的底层代码似乎很简单,但我显然遗漏了一些东西,因为我无法配置我的 SSLContext 来匹配它。

任何人都可以在不使用 Apache HttpClient 的情况下生成一个 SSLContext 实现吗?

最佳答案

以防万一有人掉到这里,对我有用的(唯一)解决方案是创建 OkHttpClient 就像解释 here .

代码如下:

private static OkHttpClient getUnsafeOkHttpClient() {
  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) throws CertificateException {
          }

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

          @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();

    OkHttpClient.Builder builder = new OkHttpClient.Builder();
    builder.sslSocketFactory(sslSocketFactory, (X509TrustManager)trustAllCerts[0]);
    builder.hostnameVerifier(new HostnameVerifier() {
      @Override
      public boolean verify(String hostname, SSLSession session) {
        return true;
      }
    });

    OkHttpClient okHttpClient = builder.build();
    return okHttpClient;
  } catch (Exception e) {
    throw new RuntimeException(e);
  }
}

关于android - 使用 okHttp 信任所有证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25509296/

相关文章:

java - 我的 EditText 不会为我的分数加分。 Android 测验应用程序

java - 从哈希表中获取所有值

java - SSL websockets 代理通过带有客户端身份验证的 nginx 代理

使用中间证书的 SSL 握手

android - SSLPeerUnverifiedException OkHttp?

android - PutExtra 然后 GetStringExtra 仍然指向 Null?

android - OneSignal - 无法通过单击通知打开已关闭的应用程序

ruby - 第一次安装 rails 无法连接到服务器

android - 在 AsyncTask 的 doInBackground() 中使用 OkHttp 库发出 HTTP 请求会阻止 UI 操作

android - Moshi generateAdapter 不适用于 JSON 对象列表