参考:https://blog.csdn.net/weixin_54087854/article/details/134625241
https://blog.csdn.net/weixin_35647799/article/details/117684065
Android4.4.2发送https请求时,出现错误:
javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0xb7eabc88: Failure in SSL library, usually a protocol error error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version (external/openssl/ssl/s23_clnt.c:741 0xa4fb8d5c:0x00000000)
SSLSocket的setEnabledProtocols配置支持TLSv1.1,TLSv1.2协议
辅助类
import android.os.Build; import java.io.IOException; import java.net.InetAddress; import java.net.Socket; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; public class SSLSocketFactoryCompat extends SSLSocketFactory { private static final String[] TLS_V12_ONLY = {"TLSv1.2"}; private final SSLSocketFactory delegate; public SSLSocketFactoryCompat() throws KeyManagementException, NoSuchAlgorithmException { SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, null, null); delegate = sc.getSocketFactory(); } public SSLSocketFactoryCompat(SSLSocketFactory delegate) { if (delegate == null) { throw new NullPointerException(); } this.delegate = delegate; } @Override public String[] getDefaultCipherSuites() { return delegate.getDefaultCipherSuites(); } @Override public String[] getSupportedCipherSuites() { return delegate.getSupportedCipherSuites(); } private Socket enableTls12(Socket socket) { if (Build.VERSION.SDK_INT >= 16 && Build.VERSION.SDK_INT < 20) { if (socket instanceof SSLSocket) { ((SSLSocket) socket).setEnabledProtocols(TLS_V12_ONLY); } } return socket; } @Override public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException { return enableTls12(delegate.createSocket(s, host, port, autoClose)); } @Override public Socket createSocket(String host, int port) throws IOException { return enableTls12(delegate.createSocket(host, port)); } @Override public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException { return enableTls12(delegate.createSocket(host, port, localHost, localPort)); } @Override public Socket createSocket(InetAddress host, int port) throws IOException { return enableTls12(delegate.createSocket(host, port)); } @Override public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException { return enableTls12(delegate.createSocket(address, port, localAddress, localPort)); } }
TrustAllCerts类
import java.security.cert.X509Certificate; import javax.net.ssl.X509TrustManager; public class TrustAllCerts implements X509TrustManager { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) {} @Override public void checkServerTrusted(X509Certificate[] chain, String authType) {} @Override public X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0];} }
创建OkHttpClient方法
OkHttpClient okHttpClient = null; //日志拦截器 LoggingInterceptor loggingInterceptor = new LoggingInterceptor(); GzipRequestInterceptor gzipRequestInterceptor = new GzipRequestInterceptor(); // 邢帅杰 update 2023-08-08 新增用于https证书信任 OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.connectTimeout(timeout, TimeUnit.SECONDS);//响应时间 builder.readTimeout(timeout, TimeUnit.SECONDS);//读取时间 builder.addInterceptor(loggingInterceptor);//添加日志拦截器 // 信任https证书 builder.hostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }); //信任所有https证书 TrustAllCerts trustAllCerts = new TrustAllCerts(); //安卓系统版本号 String androidVer = String.valueOf(android.os.Build.VERSION.RELEASE);//安卓4:4.4.2 //sdk版本号 int sdkVer = Build.VERSION.SDK_INT;//安卓4:19 //创建管理器 //如果是安卓4,强制启用TLSv1.2 try { SSLContext sslContext = null; SSLSocketFactory factory = null; if (sdkVer == 19 || "4.4.2".equals(androidVer) || androidVer.startsWith("4.")) { sslContext = SSLContext.getInstance("TLSv1.2"); sslContext.init(null, new TrustManager[]{trustAllCerts}, new SecureRandom()); //为OkHttpClient设置sslSocketFactory factory = new SSLSocketFactoryCompat(sslContext.getSocketFactory()); } else { sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, new TrustManager[]{trustAllCerts}, new SecureRandom()); factory = sslContext.getSocketFactory(); } builder.sslSocketFactory(factory, trustAllCerts); okHttpClient = builder.build(); } catch (Exception e) { e.printStackTrace(); }