gpt4 book ai didi

android - 如何将可信证书添加到 OkHttp

转载 作者:行者123 更新时间:2023-11-29 22:46:15 25 4
gpt4 key购买 nike

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

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

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

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

除外

预期行为:OkHttp 可以连接到默认信任的所有服务器(我不想盲目信任所有服务器)包括 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 之外的所有服务器时出现异常:

javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:361)
at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:336)
at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:300)
at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:185)
at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.java:224)
at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.java:107)
at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.java:87)
at okhttp3.internal.connection.Transmitter.newExchange(Transmitter.java:169)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:41)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:94)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:88)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
at com.sanctusmedia.android.WattsUp.network.OkHttpSingleton$ObedientCacheInterceptor.intercept(OkHttpSingleton.java:121)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:221)
at okhttp3.RealCall.execute(RealCall.java:81)

最佳答案

第一个选项是添加到本地 keystore 文件,存储在 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()
}
}

关于android - 如何将可信证书添加到 OkHttp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58413452/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com