问题
I am trying to make Android app, where I can get and parse HTML (from site which doesnt have API). I am using OkHttp. The site has untrusted (but valid) certificate. I am getting:
java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
I've already set up the official way (https://developer.android.com/training/articles/security-ssl#java) and now I need to link it with OkHttpClient.
I tried
OkHttpClient client = new OkHttpClient;
OkHttpClient.Builder builder = client.newBuilder();
builder.sslSocketFactory(sslcontext.getSocketFactory()).build();
But it doesnt work, and also it is deprecated. Thanks
回答1:
You need to use sslSocketFactory(SSLSocketFactory sslSocketFactory, X509TrustManager trustManager)
which is not deprecated.
Use this variable (which creates a trust manager that does not validate certificate chains):
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[]{};
}
}
};
and pass to sslSocketFactory()
in this way:
builder.sslSocketFactory(sslSocketFactory, (X509TrustManager)trustAllCerts[0]);
also apply this to verify every host:
builder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
回答2:
See this documented example for adding a known trusted certificate
https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/CustomTrust.java
public CustomTrust() {
X509TrustManager trustManager;
SSLSocketFactory sslSocketFactory;
try {
trustManager = trustManagerForCertificates(trustedCertificatesInputStream());
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[] { trustManager }, null);
sslSocketFactory = sslContext.getSocketFactory();
} catch (GeneralSecurityException e) {
throw new RuntimeException(e);
}
client = new OkHttpClient.Builder()
.sslSocketFactory(sslSocketFactory, trustManager)
.build();
}
来源:https://stackoverflow.com/questions/53304082/adding-a-custom-certificate-to-an-okhttp-client