Android异常:java.lang.IllegalStateException: Unable to extract the trust manager on Android10Platform, sslSocketFactory is class com.android.org.conscrypt.OpenSSLSocketFactoryImpl
web、java项目异常:javax.net.ssl. SSLHandshakeException:PKIX path building failed
以下解决,第一步创建NullHostNameVerifier
package com.malx.signature.network;
import android.annotation.SuppressLint;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
/**
* @author by maliang on 2021/12/13 17:25
* #First Created Time:
* #包名:com.malx.signature
* class description:用于主机名验证,此不校验允许所有。
*/
public class NullHostNameVerifier implements HostnameVerifier {
/**
* Verify that the host name is an acceptable match with
* the server's authentication scheme.
*
* @param hostname the host name
* @param session SSLSession used on the connection to host
* @return true if the host name is acceptable
*/
@SuppressLint("BadHostnameVerifier")
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
第二步 :
创建OkHttpClient示例(中间其他配置代码省略...):
import java.net.Proxy;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext;
import javax.net.ssl.X509TrustManager;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
...
OkHttpClient.Builder builder = new OkHttpClient.Builder();
...
try {
X509TrustManager trustManager = new X509TrustManager() {
/**
* Given the partial or complete certificate chain provided by the
* peer, build a certificate path to a trusted root and return if
* it can be validated and is trusted for client SSL
* authentication based on the authentication type.
* <p>
* The authentication type is determined by the actual certificate
* used. For instance, if RSAPublicKey is used, the authType
* should be "RSA". Checking is case-sensitive.
*
* @param chain the peer certificate chain
* @param authType the authentication type based on the client certificate
* @throws IllegalArgumentException if null or zero-length chain
* is passed in for the chain parameter or if null or zero-length
* string is passed in for the authType parameter
* @throws CertificateException if the certificate chain is not trusted
* by this TrustManager.
*/
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
/**
* Given the partial or complete certificate chain provided by the
* peer, build a certificate path to a trusted root and return if
* it can be validated and is trusted for server SSL
* authentication based on the authentication type.
* <p>
* The authentication type is the key exchange algorithm portion
* of the cipher suites represented as a String, such as "RSA",
* "DHE_DSS". Note: for some exportable cipher suites, the key
* exchange algorithm is determined at run time during the
* handshake. For instance, for TLS_RSA_EXPORT_WITH_RC4_40_MD5,
* the authType should be RSA_EXPORT when an ephemeral RSA key is
* used for the key exchange, and RSA when the key from the server
* certificate is used. Checking is case-sensitive.
*
* @param chain the peer certificate chain
* @param authType the key exchange algorithm used
* @throws IllegalArgumentException if null or zero-length chain
* is passed in for the chain parameter or if null or zero-length
* string is passed in for the authType parameter
* @throws CertificateException if the certificate chain is not trusted
* by this TrustManager.
*/
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
/**
* Return an array of certificate authority certificates
* which are trusted for authenticating peers.
*
* @return a non-null (possibly empty) array of acceptable
* CA issuer certificates.
*/
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
};
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new X509TrustManager[]{trustManager}, new SecureRandom());
builder.sslSocketFactory(sslContext.getSocketFactory(), trustManager);
builder.hostnameVerifier(new NullHostNameVerifier());
} catch (IllegalStateException | NoSuchAlgorithmException | KeyManagementException e) {
e.printStackTrace();
}
// 不使用代理,防止抓包
builder.proxy(Proxy.NO_PROXY);
// 解决网络java.net.SocketException: Socket closed问题
builder.addNetworkInterceptor(new Interceptor() {
@NonNull
@Override
public Response intercept(@NonNull Chain chain) throws IOException {
// ("Connection", "keep-alive") close
Request.Builder newBuilder = chain.request().newBuilder();
// 这个是默认情况下,如果服务器自定义需要使用自定义方式解决
newBuilder.addHeader("Connection", "keep-alive")
.addHeader("Accept-Charset", "UTF-8");
Request request = newBuilder.build();
return chain.proceed(request);
}
});
OkHttpClient okHttpClient = builder.build();
...
|