如何将可信证书添加到OkHttp

时间:2019-10-16 12:34:11

标签: android certificate okhttp

我需要使用OkHttp客户端信任一个特定站点的证书。我在这里找到了解决方案:https://jebware.com/blog/?p=340

此代码与我想信任的服务器配合使用。 唯一的问题是,现在没有其他服务器可以信任!:D所以显然不是很理想...

我只希望OkHttp保留其默认行为,并只需添加我自己的受信任证书即可。

当前行为:OkHttp无法使用HTTPS连接到任何服务器,除了myaccount.esbecars.com

预期的行为::OkHttp可以连接到默认情况下受信任的所有服务器(我不想不想盲目地信任所有服务器)包括 { {1}}

感谢您的建议!

我正在使用以下代码:

myaccount.esbecars.com

尝试连接除SSLContext sslContext; TrustManager[] trustManagers; try { KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(null, null); InputStream certInputStream = context.getAssets().open("esb_ireland.pem"); BufferedInputStream bis = new BufferedInputStream(certInputStream); CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); while (bis.available() > 0) { Certificate cert = certificateFactory.generateCertificate(bis); keyStore.setCertificateEntry("myaccount.esbecars.com", cert); } TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(keyStore); trustManagers = trustManagerFactory.getTrustManagers(); sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, trustManagers, null); instance = new OkHttpClient.Builder() .cache(myCache) .connectTimeout(FrontendConstants.NETWORK_CONNECT_TIMEOUT, TimeUnit.MILLISECONDS) .readTimeout(FrontendConstants.NETWORK_READ_TIMEOUT, TimeUnit.MILLISECONDS) .addInterceptor(new ObedientCacheInterceptor()) .sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustManagers[0]) .build(); } catch (Exception e) { e.printStackTrace(); //TODO replace with real exception handling tailored to your needs } 以外的所有服务器时出现异常:

myaccount.esbecars.com

1 个答案:

答案 0 :(得分:1)

第一个选项是添加到本地密钥库文件中,该文件存储在JRE目录中。

但是我还使用了一个自定义信任管理器,它可以合并证书https://github.com/yschimke/okurl/blob/07e79795e14b9163bcf4342f39c23020f51ecf64/src/main/kotlin/com/baulsupp/okurl/security/MergedX509TrustManager.kt

https://github.com/yschimke/okurl/blob/0520489d697d49b179010e468a87ef0749ff95be/src/main/kotlin/com/baulsupp/okurl/security/CertificateUtils.kt

package com.baulsupp.okurl.security

import java.security.cert.CertificateException
import java.security.cert.X509Certificate
import javax.net.ssl.X509TrustManager

class MergedX509TrustManager(private val managers: List<X509TrustManager>) : X509TrustManager {

  override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {
    throw UnsupportedOperationException()
  }

  override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {
    val exceptions = mutableListOf<CertificateException>()

    for (tm in managers) {
      try {
        tm.checkServerTrusted(chain, authType)
        return
      } catch (e: CertificateException) {
        exceptions.add(e)
      }
    }

    throw bestException(exceptions)
  }

  fun bestException(exceptions: List<CertificateException>): CertificateException {
    if (exceptions.isNotEmpty()) {
      // last is probably system keystore
      throw exceptions[exceptions.size - 1]
    } else {
      throw CertificateException("no X509TrustManager to check")
    }
  }

  override fun getAcceptedIssuers(): Array<X509Certificate> {
    val certificates = mutableListOf<X509Certificate>()

    for (tm in managers) {
      certificates.addAll(tm.acceptedIssuers.toList())
    }

    return certificates.toTypedArray()
  }
}