diff --git a/app/src/main/java/qianmu/container/app/MyApplication.java b/app/src/main/java/qianmu/container/app/MyApplication.java index b7fad40..eb37625 100644 --- a/app/src/main/java/qianmu/container/app/MyApplication.java +++ b/app/src/main/java/qianmu/container/app/MyApplication.java @@ -138,59 +138,22 @@ public class MyApplication extends Application { } } - // private RefWatcher refWatcher; - // public static RefWatcher getRefWatcher(Context context) { - // MyApplication application = (MyApplication) context.getApplicationContext(); - // return application.refWatcher; - // } - // 初始化下载框架 private void initOkGo() { try { - OkHttpClient client; - try{ - OkHttpClient.Builder builder = new OkHttpClient.Builder(); - builder.readTimeout(10, TimeUnit.SECONDS); - builder.writeTimeout(10, TimeUnit.SECONDS); - builder.connectTimeout(10, TimeUnit.SECONDS); - builder.sslSocketFactory(SSLSocketClient.getSSLSocketFactory());// 过滤https证书 - builder.hostnameVerifier(SSLSocketClient.getHostnameVerifier()); - client = builder.build(); - } catch(Exception e) { - client = createOkHttpClient(this); - } + int currentApiVersion = android.os.Build.VERSION.SDK_INT; + OkHttpClient.Builder builder = new OkHttpClient.Builder(); + builder.readTimeout(10, TimeUnit.SECONDS); + builder.writeTimeout(10, TimeUnit.SECONDS); + builder.connectTimeout(10, TimeUnit.SECONDS); + builder.sslSocketFactory(SSLSocketClient.getSSLSocketFactory(), SSLSocketClient.getX509TrustManager()); + builder.hostnameVerifier(SSLSocketClient.getHostnameVerifier()); + OkHttpClient client = builder.build(); OkGo.getInstance().init(this).setOkHttpClient(client).setRetryCount(0); } catch (Throwable t) { LoggerUtil.e("initOkGo", StringUtil.getThrowableStr(t)); } } - - - public OkHttpClient createOkHttpClient(Context context) { - try { - // 获取系统默认信任管理器 - TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance( - TrustManagerFactory.getDefaultAlgorithm()); - trustManagerFactory.init((KeyStore) null); - TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); - X509TrustManager trustManager = (X509TrustManager) trustManagers[0]; - - // 初始化 SSL 上下文 - SSLContext sslContext = SSLContext.getInstance("TLS"); - sslContext.init(null, new TrustManager[]{trustManager}, null); - - // 构建 OkHttpClient(3.x 版本同样需要显式传入 trustManager) - return new OkHttpClient.Builder() - .sslSocketFactory(sslContext.getSocketFactory(), trustManager) // 关键 - .connectTimeout(15, TimeUnit.SECONDS) - .readTimeout(15, TimeUnit.SECONDS) - .writeTimeout(15, TimeUnit.SECONDS) - .build(); - } catch (Exception e) { - throw new RuntimeException("OkHttp 初始化失败", e); - } - } - // 页面常亮 private void initWakeLock() { powerManager = (PowerManager) this.getSystemService(Service.POWER_SERVICE); diff --git a/app/src/main/java/qianmu/container/http/retrofit/RetrofitUtil.java b/app/src/main/java/qianmu/container/http/retrofit/RetrofitUtil.java index 535ed3d..3d7af83 100644 --- a/app/src/main/java/qianmu/container/http/retrofit/RetrofitUtil.java +++ b/app/src/main/java/qianmu/container/http/retrofit/RetrofitUtil.java @@ -35,28 +35,9 @@ public class RetrofitUtil { private static OkHttpClient initOkHttpClient(int timeout) { try { - final TrustManager[] trustAllCerts = new TrustManager[]{new 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]; - } - }}; - final SSLContext sslContext = SSLContext.getInstance("TLS"); - sslContext.init(null, trustAllCerts, new SecureRandom()); - final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); - - return new OkHttpClient.Builder().sslSocketFactory(sslSocketFactory) + return new OkHttpClient.Builder().sslSocketFactory(SSLSocketClient.getSSLSocketFactory(), SSLSocketClient.getX509TrustManager()) .retryOnConnectionFailure(true) -// .addInterceptor(new BaseInterceptor()) - .hostnameVerifier(org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER) + .hostnameVerifier(SSLSocketClient.getHostnameVerifier()) .connectTimeout(timeout, TimeUnit.SECONDS).readTimeout(timeout, TimeUnit.SECONDS) .writeTimeout(timeout, TimeUnit.SECONDS).build(); } catch (Throwable t) { diff --git a/app/src/main/java/qianmu/container/mqtt/MQTTService.java b/app/src/main/java/qianmu/container/mqtt/MQTTService.java index 8311d06..3b305ca 100644 --- a/app/src/main/java/qianmu/container/mqtt/MQTTService.java +++ b/app/src/main/java/qianmu/container/mqtt/MQTTService.java @@ -182,8 +182,9 @@ public class MQTTService extends Service { // 用户名 conOpt.setUserName(userName); // 密码 - conOpt.setPassword(passWord.toCharArray()); //将字符串转换为字符串数组 - + if(!StringUtil.isEmpty(passWord)){ + conOpt.setPassword(passWord.toCharArray()); //将字符串转换为字符串数组 + } // conOpt.setAutomaticReconnect(true); // last will message diff --git a/app/src/main/java/qianmu/container/socket/CustomSSLSocketFactory.java b/app/src/main/java/qianmu/container/socket/CustomSSLSocketFactory.java new file mode 100644 index 0000000..1323fe0 --- /dev/null +++ b/app/src/main/java/qianmu/container/socket/CustomSSLSocketFactory.java @@ -0,0 +1,66 @@ +package qianmu.container.socket; + + +import java.io.IOException; +import java.net.InetAddress; +import java.net.Socket; +import java.net.UnknownHostException; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; + +public class CustomSSLSocketFactory extends SSLSocketFactory { + private final SSLSocketFactory delegate; + + public CustomSSLSocketFactory(SSLSocketFactory delegate) { + this.delegate = delegate; + } + + @Override + public String[] getDefaultCipherSuites() { + return delegate.getDefaultCipherSuites(); + } + + @Override + public String[] getSupportedCipherSuites() { + return delegate.getSupportedCipherSuites(); + } + + @Override + public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException { + Socket socket = delegate.createSocket(s, host, port, autoClose); + return wrapSocket(socket); + } + + @Override + public Socket createSocket(String host, int port) throws IOException, UnknownHostException { + Socket socket = delegate.createSocket(host, port); + return wrapSocket(socket); + } + + @Override + public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException { + Socket socket = delegate.createSocket(host, port, localHost, localPort); + return wrapSocket(socket); + } + + @Override + public Socket createSocket(InetAddress host, int port) throws IOException { + Socket socket = delegate.createSocket(host, port); + return wrapSocket(socket); + } + + @Override + public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException { + Socket socket = delegate.createSocket(address, port, localAddress, localPort); + return wrapSocket(socket); + } + + // 关键:包装 Socket,确保使用我们的 TrustManager 逻辑 + private Socket wrapSocket(Socket socket) { + if (socket instanceof SSLSocket) { + // 可在此处强制设置 TLS 版本等参数(如 Android 14 要求的 TLSv1.2+) + ((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1.2", "TLSv1.3"}); + } + return socket; + } +} diff --git a/app/src/main/java/qianmu/container/util/SSLSocketClient.java b/app/src/main/java/qianmu/container/util/SSLSocketClient.java index 92d5038..f4c53a2 100644 --- a/app/src/main/java/qianmu/container/util/SSLSocketClient.java +++ b/app/src/main/java/qianmu/container/util/SSLSocketClient.java @@ -1,15 +1,22 @@ package qianmu.container.util; +import android.annotation.SuppressLint; + +import java.security.KeyStore; import java.security.SecureRandom; import java.security.cert.X509Certificate; +import java.util.Arrays; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; +import qianmu.container.socket.CustomSSLSocketFactory; + /** * Created by Android Studio. * User: linzhibin @@ -18,47 +25,43 @@ import javax.net.ssl.X509TrustManager; */ public class SSLSocketClient { - //获取这个SSLSocketFactory + // 全局唯一 TrustManager(必须与 SSLSocketFactory 绑定) + private static final X509TrustManager X509 = new X509TrustManager() { + @SuppressLint("TrustAllX509TrustManager") + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) {} + + @SuppressLint("TrustAllX509TrustManager") + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) {} + + @Override + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } + }; + + // 获取包装后的 SSLSocketFactory(强制绑定 TrustManager) public static SSLSocketFactory getSSLSocketFactory() { try { - SSLContext sslContext = SSLContext.getInstance("SSL"); - sslContext.init(null, getTrustManager(), new SecureRandom()); - return sslContext.getSocketFactory(); + // 1. 使用 TLSv1.2 协议(Android 14 强制要求) + SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); + // 2. 绑定我们的 TrustManager + sslContext.init(null, new TrustManager[]{X509}, new SecureRandom()); + // 3. 用自定义类包装,避免系统替换 + return new CustomSSLSocketFactory(sslContext.getSocketFactory()); } catch (Exception e) { - throw new RuntimeException(e); + throw new RuntimeException("创建 SSLSocketFactory 失败", e); } } - //获取TrustManager - private static TrustManager[] getTrustManager() { - TrustManager[] trustAllCerts = new TrustManager[]{ - new X509TrustManager() { - @Override - public void checkClientTrusted(X509Certificate[] chain, String authType) { - } - - @Override - public void checkServerTrusted(X509Certificate[] chain, String authType) { - } - - @Override - public X509Certificate[] getAcceptedIssuers() { - return new X509Certificate[]{}; - } - } - }; - return trustAllCerts; + // 获取 HostnameVerifier + public static HostnameVerifier getHostnameVerifier() { + return (s, sslSession) -> true; // 生产环境需严格校验 } - //获取HostnameVerifier - public static HostnameVerifier getHostnameVerifier() { - HostnameVerifier hostnameVerifier = new HostnameVerifier() { - @Override - public boolean verify(String s, SSLSession sslSession) { - return true; - } - }; - return hostnameVerifier; + // 暴露 TrustManager 供 OkHttp 绑定 + public static X509TrustManager getX509TrustManager() { + return X509; } - }