From ba27de7d3b5fa114e767624a4469aad56eedd60c Mon Sep 17 00:00:00 2001 From: fengyuecanzhu <1021300691@qq.com> Date: Thu, 13 May 2021 17:18:55 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/libs/sun.misc.BASE64Decoder.jar | Bin 7471 -> 0 bytes .../xyz/fycz/myreader/application/App.java | 6 +- .../java/xyz/fycz/myreader/util/Coder.java | 102 ---- .../java/xyz/fycz/myreader/util/HttpUtil.java | 496 ------------------ .../java/xyz/fycz/myreader/util/RSACoder.java | 289 ---------- .../xyz/fycz/myreader/util/RSAUtilV2.java | 478 ----------------- .../fycz/myreader/util/SSLSocketClient.java | 118 +++++ .../myreader/util/utils/JsExtensions.java | 7 +- .../fycz/myreader/util/utils/OkHttpUtils.java | 33 +- .../xyz/fycz/myreader/util/webdav/WebDav.kt | 9 +- .../fycz/myreader/webapi/HttpDataSource.java | 125 ----- .../fycz/myreader/widget/page/PageLoader.java | 2 +- 12 files changed, 156 insertions(+), 1509 deletions(-) delete mode 100644 app/libs/sun.misc.BASE64Decoder.jar delete mode 100644 app/src/main/java/xyz/fycz/myreader/util/Coder.java delete mode 100644 app/src/main/java/xyz/fycz/myreader/util/HttpUtil.java delete mode 100644 app/src/main/java/xyz/fycz/myreader/util/RSACoder.java delete mode 100644 app/src/main/java/xyz/fycz/myreader/util/RSAUtilV2.java create mode 100644 app/src/main/java/xyz/fycz/myreader/util/SSLSocketClient.java delete mode 100644 app/src/main/java/xyz/fycz/myreader/webapi/HttpDataSource.java diff --git a/app/libs/sun.misc.BASE64Decoder.jar b/app/libs/sun.misc.BASE64Decoder.jar deleted file mode 100644 index 9811c130389b95328a689e9f9466d42624445500..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7471 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 diff --git a/app/src/main/java/xyz/fycz/myreader/application/App.java b/app/src/main/java/xyz/fycz/myreader/application/App.java index 3536e01..b5ecb92 100644 --- a/app/src/main/java/xyz/fycz/myreader/application/App.java +++ b/app/src/main/java/xyz/fycz/myreader/application/App.java @@ -37,10 +37,8 @@ import java.security.cert.X509Certificate; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; @@ -55,7 +53,7 @@ import xyz.fycz.myreader.ui.activity.MainActivity; import xyz.fycz.myreader.ui.dialog.APPDownloadTip; import xyz.fycz.myreader.ui.dialog.DialogCreator; import xyz.fycz.myreader.ui.fragment.BookcaseFragment; -import xyz.fycz.myreader.util.HttpUtil; +import xyz.fycz.myreader.util.SSLSocketClient; import xyz.fycz.myreader.util.SharedPreUtils; import xyz.fycz.myreader.util.StringHelper; import xyz.fycz.myreader.util.ToastUtils; @@ -79,7 +77,7 @@ public class App extends Application { application = this; debug = isApkInDebug(this); firstInit(); - HttpUtil.trustAllHosts();//信任所有证书 + SSLSocketClient.trustAllHosts();//信任所有证书 RxJavaPlugins.setErrorHandler(Functions.emptyConsumer()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { webviewSetPath(this); diff --git a/app/src/main/java/xyz/fycz/myreader/util/Coder.java b/app/src/main/java/xyz/fycz/myreader/util/Coder.java deleted file mode 100644 index 9bedab2..0000000 --- a/app/src/main/java/xyz/fycz/myreader/util/Coder.java +++ /dev/null @@ -1,102 +0,0 @@ -package xyz.fycz.myreader.util; - -import java.security.MessageDigest; - -import javax.crypto.KeyGenerator; -import javax.crypto.Mac; -import javax.crypto.SecretKey; -import javax.crypto.spec.SecretKeySpec; - -import Decoder.BASE64Decoder; -import Decoder.BASE64Encoder; - - -public abstract class Coder { - public static final String KEY_SHA = "SHA"; - public static final String KEY_MD5 = "MD5"; - - /** - * MAC算法可选以下多种算法 - *
-     * HmacMD5 
-     * HmacSHA1 
-     * HmacSHA256 
-     * HmacSHA384 
-     * HmacSHA512
-     * 
- */ - public static final String KEY_MAC = "HmacMD5"; - - /** - * BASE64解密 - * @param key - * @return - * @throws Exception - */ - public static byte[] decryptBASE64( String key ) throws Exception { - return (new BASE64Decoder()).decodeBuffer(key); - } - - /** - * BASE64加密 - * @param key - * @return - * @throws Exception - */ - public static String encryptBASE64(byte[] key) throws Exception { - return (new BASE64Encoder()).encodeBuffer(key); - } - - /** - * MD5 加密 - * @param data - * @return - * @throws Exception - */ - public static byte[] encryptMD5( byte[] data) throws Exception { - MessageDigest md5 = MessageDigest.getInstance(KEY_MD5); - md5.update(data); - - return md5.digest(); - } - - /** - * SHA 加密 - * @param data - * @return - * @throws Exception - */ - public static byte[] encryptSHA( byte[] data) throws Exception { - MessageDigest sha = MessageDigest.getInstance(KEY_SHA); - sha.update(data); - - return sha.digest(); - } - - /** - * 初始化HMAC密钥 - * - * @return - * @throws Exception - */ - public static String initMacKey() throws Exception { - KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC); - - SecretKey secretKey = keyGenerator.generateKey(); - return encryptBASE64(secretKey.getEncoded()); - } - - /** - * HMAC 加密 - * @param data - * @param key - * @return - * @throws Exception - */ - public static byte[] encryptHMAC( byte[] data, String key) throws Exception { - SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC); - Mac mac = Mac.getInstance(secretKey.getAlgorithm()); - mac.init(secretKey); - return mac.doFinal(data); - } -} \ No newline at end of file diff --git a/app/src/main/java/xyz/fycz/myreader/util/HttpUtil.java b/app/src/main/java/xyz/fycz/myreader/util/HttpUtil.java deleted file mode 100644 index a5c9550..0000000 --- a/app/src/main/java/xyz/fycz/myreader/util/HttpUtil.java +++ /dev/null @@ -1,496 +0,0 @@ -package xyz.fycz.myreader.util; - -import android.annotation.SuppressLint; -import android.graphics.Bitmap; -import android.util.Base64; -import android.util.Log; - -import com.google.gson.Gson; -import okhttp3.*; -import xyz.fycz.myreader.R; -import xyz.fycz.myreader.application.App; -import xyz.fycz.myreader.webapi.callback.HttpCallback; -import xyz.fycz.myreader.webapi.callback.JsonCallback; -import xyz.fycz.myreader.webapi.callback.URLConnectionCallback; -import xyz.fycz.myreader.common.APPCONST; -import xyz.fycz.myreader.common.URLCONST; -import xyz.fycz.myreader.entity.JsonModel; - -import java.io.*; -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLConnection; -import java.security.SecureRandom; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.util.*; -import java.util.concurrent.TimeUnit; - -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocketFactory; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; - -import static java.lang.String.valueOf; - - -public class HttpUtil { - - private static String sessionid; - //最好只使用一个共享的OkHttpClient 实例,将所有的网络请求都通过这个实例处理。 - //因为每个OkHttpClient 实例都有自己的连接池和线程池,重用这个实例能降低延时,减少内存消耗,而重复创建新实例则会浪费资源。 - private static OkHttpClient mClient; - - public static SSLSocketFactory createSSLSocketFactory() { - SSLSocketFactory ssfFactory = null; - try { - SSLContext sc = SSLContext.getInstance("TLS"); - sc.init(null, new TrustManager[]{new TrustAllCerts()}, new SecureRandom()); - ssfFactory = sc.getSocketFactory(); - } catch (Exception e) { - } - - return ssfFactory; - } - static 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];} - } - - public static X509TrustManager createTrustAllManager() { - X509TrustManager tm = null; - try { - tm = new X509TrustManager() { - @SuppressLint("TrustAllX509TrustManager") - public void checkClientTrusted(X509Certificate[] chain, String authType) { - //do nothing,接受任意客户端证书 - } - - @SuppressLint("TrustAllX509TrustManager") - public void checkServerTrusted(X509Certificate[] chain, String authType) { - //do nothing,接受任意服务端证书 - } - - public X509Certificate[] getAcceptedIssuers() { - return new X509Certificate[0]; - } - }; - } catch (Exception ignored) { - } - return tm; - } - - private static Interceptor getHeaderInterceptor() { - return chain -> { - Request request = chain.request() - .newBuilder() - .addHeader("Keep-Alive", "300") - .addHeader("Connection", "Keep-Alive") - .addHeader("Cache-Control", "no-cache") - .build(); - return chain.proceed(request); - }; - } - - public static synchronized OkHttpClient getOkHttpClient() { - if (mClient == null) { - OkHttpClient.Builder builder = new OkHttpClient.Builder(); - builder.connectTimeout(5, TimeUnit.SECONDS) - .readTimeout(10, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .sslSocketFactory(createSSLSocketFactory(), createTrustAllManager()) - .hostnameVerifier((hostname, session) -> true) - .protocols(Collections.singletonList(Protocol.HTTP_1_1)) - .addInterceptor(getHeaderInterceptor()); - mClient = builder - .build(); - } - return mClient; - - } - - - /** - * 图片发送 - * - * @param address - * @param callback - */ - public static void sendBitmapGetRequest(final String address, final HttpCallback callback) { - new Thread(new Runnable() { - HttpURLConnection connection = null; - - @Override - public void run() { - try { - URL url = new URL(address); - connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("GET"); - connection.setRequestProperty("Content-type", "application/octet-stream"); - connection.setRequestProperty("Accept-Charset", "utf-8"); - connection.setRequestProperty("contentType", "utf-8"); - connection.setConnectTimeout(10000); - connection.setReadTimeout(10000); - connection.setDoInput(true); - connection.setDoOutput(true); - InputStream in = connection.getInputStream(); - if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) { - Log.e("Http", "网络错误异常!!!!"); - } - Log.d("Http", "connection success"); - if (callback != null) { - callback.onFinish(in); - } - } catch (Exception e) { - Log.e("Http", e.toString()); - if (callback != null) { - callback.onError(e); - } - } finally { - if (connection != null) { - connection.disconnect(); - } - } - } - - }).start(); - } - - /** - * get请求 - * - * @param address - * @param callback - */ - public static void sendGetRequest(final String address, final HttpCallback callback) { - new Thread(new Runnable() { - HttpURLConnection connection = null; - - @Override - public void run() { - try { - URL url = new URL(address); - connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("GET"); - connection.setRequestProperty("Content-type", "text/html"); - connection.setRequestProperty("Accept-Charset", "utf-8"); - connection.setRequestProperty("contentType", "utf-8"); - connection.setConnectTimeout(60 * 1000); - connection.setReadTimeout(60 * 1000); - connection.setDoInput(true); - connection.setDoOutput(true); - if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) { - Log.e("Http", "网络错误异常!!!!"); - } - InputStream in = connection.getInputStream(); - Log.d("Http", "connection success"); - if (callback != null) { - callback.onFinish(in); - } - } catch (Exception e) { - e.printStackTrace(); - Log.e("Http", e.toString()); - if (callback != null) { - callback.onError(e); - } - } finally { - if (connection != null) { - connection.disconnect(); - } - } - } - }).start(); - } - - /** - * 网络通信测试请求 - * - * @param address - * @param callback - */ - public static void sendTestGetRequest(final String address, final HttpCallback callback) { - new Thread(new Runnable() { - HttpURLConnection connection = null; - - @Override - public void run() { - try { - URL url = new URL(address); - connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("GET"); - connection.setRequestProperty("Content-type", "text/html"); - connection.setRequestProperty("Accept-Charset", "utf-8"); - connection.setRequestProperty("contentType", "utf-8"); - connection.setConnectTimeout(3 * 1000); - connection.setReadTimeout(3 * 1000); - connection.setDoInput(true); - connection.setDoOutput(true); - if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) { - Log.e("Http", "网络错误异常!!!!"); - } - InputStream in = connection.getInputStream(); - Log.d("Http", "connection success"); - if (callback != null) { - callback.onFinish(in); - } - } catch (Exception e) { - e.printStackTrace(); - Log.e("Http", e.toString()); - if (callback != null) { - callback.onError(e); - } - } finally { - if (connection != null) { - connection.disconnect(); - } - } - } - }).start(); - } - - public static void sendGetRequest_okHttp(final String address, boolean isRefresh, final HttpCallback callback) { - App.getApplication().newThread(() -> { - try { - OkHttpClient client = getOkHttpClient(); - Request.Builder requestBuilder = new Request.Builder() - .addHeader("Accept", "*/*") - .addHeader("Connection", "Keep-Alive") - //.addHeader("Charsert", "utf-8") - .addHeader("Cache-Control", "no-cache") - .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36"); - if (address.contains("qidian.com")) { - SharedPreUtils spu = SharedPreUtils.getInstance(); - String cookie = spu.getString(App.getmContext().getString(R.string.qdCookie), ""); - if (cookie.equals("")) { - requestBuilder.addHeader("cookie", "_csrfToken=eXRDlZxmRDLvFAmdgzqvwWAASrxxp2WkVlH4ZM7e; newstatisticUUID=1595991935_2026387981"); - } else { - requestBuilder.addHeader("cookie", cookie); - } - } - requestBuilder.url(address); - Response response = client.newCall(requestBuilder.build()).execute(); - callback.onFinish(response.body().byteStream()); - } catch (Exception e) { - e.printStackTrace(); - callback.onError(e); - } - }); - } - - /** - * post请求 - * - * @param address - * @param output - * @param callback - */ - public static void sendPostRequest(final String address, final String output, final HttpCallback callback) { - App.getApplication().newThread(new Runnable() { - HttpURLConnection connection = null; - - @Override - public void run() { - try { - URL url = new URL(address); - connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("POST"); - connection.setConnectTimeout(60 * 1000); - connection.setReadTimeout(60 * 1000); - connection.setRequestProperty("user-agent", - "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4168.3 Safari/537.36"); - connection.setDoInput(true); - connection.setDoOutput(true); - if (output != null) { - // 获取URLConnection对象对应的输出流 - PrintWriter out = new PrintWriter(connection.getOutputStream()); - // 发送请求参数 - out.print(output); - // flush输出流的缓冲 - out.flush(); - } - InputStream in = connection.getInputStream(); - if (callback != null) { - callback.onFinish(in); - } - } catch (Exception e) { - if (callback != null) { - callback.onError(e); - } - } finally { - if (connection != null) { - connection.disconnect(); - } - } - } - }); - } - - /** - * post请求 获取蓝奏云直链 - * - * @param address - * @param output - * @param callback - */ - public static void sendPostRequest(final String address, final String output, final HttpCallback callback, final String referer) { - new Thread(new Runnable() { - HttpURLConnection connection = null; - - @Override - public void run() { - try { - URL url = new URL(address); - connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("POST"); - connection.setConnectTimeout(60 * 1000); - connection.setReadTimeout(60 * 1000); - connection.setRequestProperty("Referer", referer); - connection.setRequestProperty("user-agent", - "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4168.3 Safari/537.36"); - connection.setDoInput(true); - connection.setDoOutput(true); - if (output != null) { - DataOutputStream out = new DataOutputStream(connection.getOutputStream()); - out.writeBytes(output); - } - InputStream in = connection.getInputStream(); - if (callback != null) { - callback.onFinish(in); - } - } catch (Exception e) { - if (callback != null) { - callback.onError(e); - } - } finally { - if (connection != null) { - connection.disconnect(); - } - } - } - }).start(); - } - - /** - * 生成URL - * - * @param p_url - * @param params - * @return - */ - public static String makeURL(String p_url, Map params) { - if (params == null) return p_url; - StringBuilder url = new StringBuilder(p_url); - Log.d("http", p_url); - if (url.indexOf("?") < 0) - url.append('?'); - for (String name : params.keySet()) { - Log.d("http", name + "=" + params.get(name)); - url.append('&'); - url.append(name); - url.append('='); - try { - if (URLCONST.isRSA) { - if (name.equals("token")) { - url.append(valueOf(params.get(name))); - } else { - url.append(StringHelper.encode(Base64.encodeToString(RSAUtilV2.encryptByPublicKey(valueOf(params.get(name)).getBytes(), APPCONST.publicKey), Base64.DEFAULT).replace("\n", ""))); - } - } else { - url.append(valueOf(params.get(name))); - } - } catch (Exception e) { - e.printStackTrace(); - } - //不做URLEncoder处理 -// try { -// url.append(URLEncoder.encode(String.valueOf(params.get(name)), UTF_8)); -// } catch (UnsupportedEncodingException e) { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } - } - return url.toString().replace("?&", "?"); - } - - - /** - * 生成post输出参数串 - * - * @param params - * @return - */ - public static String makePostOutput(Map params) { - StringBuilder output = new StringBuilder(); - Iterator it = params.keySet().iterator(); - while (true) { - String name = it.next(); - Log.d("http", name + "=" + params.get(name)); - output.append(name); - output.append('='); - try { - if (URLCONST.isRSA) { - if (name.equals("token")) { - output.append(valueOf(params.get(name))); - } else { - output.append(StringHelper.encode(Base64.encodeToString(RSAUtilV2.encryptByPublicKey(valueOf(params.get(name)).getBytes(), APPCONST.publicKey), Base64.DEFAULT).replace("\n", ""))); - } - } else { - output.append(valueOf(params.get(name))); - } - } catch (Exception e) { - e.printStackTrace(); - } - if (!it.hasNext()) { - break; - } - output.append('&'); - //不做URLEncoder处理 -// try { -// url.append(URLEncoder.encode(String.valueOf(params.get(name)), UTF_8)); -// } catch (UnsupportedEncodingException e) { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } - } - return output.toString(); - } - - /** - * Trust every server - dont check for any certificate - */ - public static void trustAllHosts() { - final String TAG = "trustAllHosts"; - // Create a trust manager that does not validate certificate chains - TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() { - - public java.security.cert.X509Certificate[] getAcceptedIssuers() { - return new java.security.cert.X509Certificate[]{}; - } - - public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { - Log.i(TAG, "checkClientTrusted"); - } - - public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { - Log.i(TAG, "checkServerTrusted"); - } - }}; - - // Install the all-trusting trust manager - try { - SSLContext sc = SSLContext.getInstance("TLS"); - sc.init(null, trustAllCerts, new java.security.SecureRandom()); - HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); - } catch (Exception e) { - e.printStackTrace(); - } - } - -} diff --git a/app/src/main/java/xyz/fycz/myreader/util/RSACoder.java b/app/src/main/java/xyz/fycz/myreader/util/RSACoder.java deleted file mode 100644 index 5a979ba..0000000 --- a/app/src/main/java/xyz/fycz/myreader/util/RSACoder.java +++ /dev/null @@ -1,289 +0,0 @@ -package xyz.fycz.myreader.util; - -import android.util.Base64; - -import java.security.Key; -import java.security.KeyFactory; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.Signature; -import java.security.interfaces.RSAPrivateKey; -import java.security.interfaces.RSAPublicKey; -import java.security.spec.PKCS8EncodedKeySpec; -import java.security.spec.X509EncodedKeySpec; -import java.util.HashMap; -import java.util.Map; - -import javax.crypto.Cipher; - -/** - *
*RSA安全编码组件 - * - */ -public abstract class RSACoder extends Coder { - public static final String KEY_ALGORITHM = "RSA"; - public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; - - private static final String PUBLIC_KEY = "RSAPublicKey"; - private static final String PRIVATE_KEY = "RSAPrivatekey"; - - /** - * 用私钥对信息生成数字签名 - * @param data 加密数据 - * @param privateKey 私钥 - * @return - * @throws Exception - */ - public static String sign(byte[] data, String privateKey) throws Exception { - //解密由base64编码的私钥 - byte[] keyBytes = decryptBASE64(privateKey); - - PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes); - - KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); - - //取私钥对象 - PrivateKey pKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); - - //用私钥生成数字签名 - Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); - signature.initSign(pKey); - signature.update(data); - - return encryptBASE64(signature.sign()); - } - - /** - * 校验数字签名 - * @param data 加密数据 - * @param publicKey 公钥 - * @param sign 数字签名 - * @return - * @throws Exception - */ - public static boolean verify(byte[] data, String publicKey, String sign) throws Exception { - - //解密有base64编码的公钥 - byte[] keyBytes = decryptBASE64(publicKey); - - X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); - - KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); - - //取公钥对象 - PublicKey pKey = keyFactory.generatePublic(keySpec); - - Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); - signature.initVerify(pKey); - signature.update(data); - //验证签名是否正常 - return signature.verify(decryptBASE64(sign)); - } - - /** - * 解密 - * 用私钥解密 - * @param data 加密数据 - * @param key - * @return - * @throws Exception - */ - public static byte[] decryptPrivateKey(byte[] data, String key) throws Exception { - byte[] keyBytes = decryptBASE64(key); - - //取得私钥 - PKCS8EncodedKeySpec encodedKeySpec = new PKCS8EncodedKeySpec(keyBytes); - KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM); - Key pKey = factory.generatePrivate(encodedKeySpec); - - //对数据解密 - Cipher cipher = Cipher.getInstance(factory.getAlgorithm()); - cipher.init(Cipher.DECRYPT_MODE, pKey); - - return cipher.doFinal(data); - } - - /** - * 用公钥解密 - * @param data - * @param key - * @return - * @throws Exception - */ - public static byte[] decryptByPublicKey( byte[] data, String key) throws Exception { - - //解密 - byte[] keyBytes = decryptBASE64(key); - - //取得公钥 - X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); - KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); - Key pKey = keyFactory.generatePublic(keySpec); - - //对数据解密 - Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); - cipher.init(Cipher.DECRYPT_MODE, pKey); - - return cipher.doFinal(data); - } - - /** - * 用公钥加密 - * @param data - * @param key - * @return - * @throws Exception - */ - public static byte[] encryptByPublicKey( byte[] data, String key) throws Exception { - - byte[] keyBytes = decryptBASE64(key); - - X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); - KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); - Key pKey = keyFactory.generatePublic(keySpec); - - - Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); - cipher.init(Cipher.ENCRYPT_MODE, pKey); - - return cipher.doFinal(data); - } - - /** - * 用私钥加密 - * @param data - * @param key - * @return - * @throws Exception - */ - public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception { - - byte[] keyBytes = decryptBASE64(key); - - PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); - KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); - Key privateKey = keyFactory.generatePrivate(keySpec); - - Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); - cipher.init(Cipher.ENCRYPT_MODE, privateKey); - - return cipher.doFinal(data); - } - - /** - * 取得私钥 - * @param keyMap - * @return - * @throws Exception - */ - public static String getPrivateKey(Map keyMap) throws Exception { - - Key key = (Key) keyMap.get(PRIVATE_KEY); - - return encryptBASE64(key.getEncoded()); - } - - /** - * 取得公钥 - * @param keyMap - * @return - * @throws Exception - */ - public static String getPublicKey(Map keyMap) throws Exception { - - Key key = (Key) keyMap.get(PUBLIC_KEY); - - return encryptBASE64(key.getEncoded()); - } - /** - * 初始化密钥 - * @return - * @throws Exception - */ - public static Map initKey() throws Exception { - - KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM); - keyPairGenerator.initialize(1024); - - KeyPair keyPair = keyPairGenerator.generateKeyPair(); - //公钥 - RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); - - //私钥 - RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); - - Map keyMap = new HashMap(2); - keyMap.put(PRIVATE_KEY, privateKey); - keyMap.put(PUBLIC_KEY, publicKey); - return keyMap; - } - - public static void test() throws Exception - { - Map keyMap = RSAUtilV2.genKeyPair(); - - String publicKey = RSAUtilV2.getPublicKey(keyMap).replace("\n",""); - String privateKey = RSAUtilV2.getPrivateKey(keyMap).replace("\n",""); - - System.out.println("公钥:\n" + publicKey); - System.out.println("私钥:\n" + privateKey); - System.out.println("公钥加密——私钥解密"); - String inputStr = "{\\\"mobilePhone\\\":\\\"18577113435\\\",\\\"officePhone\\\":\\\"\\\",\\\"email\\\":\\\"test1@dwb.gxi.gov.cn\\\",\\\"token\\\":\\\"d87a6879-f5d3-4327-a5a5-43ed3ec31c8d\\\",\\\"realNameSzm\\\":\\\"c\\\",\\\"realNamePy\\\":\\\"ceshi1\\\",\\\"userState\\\":\\\"1\\\",\\\"sex\\\":\\\"male\\\",\\\"duty\\\":\\\"\\\",\\\"emailPwd\\\":\\\"test1@123456\\\",\\\"jurisdiction\\\":{\\\"meeting\\\":true,\\\"file\\\":true,\\\"supervise\\\":true,\\\"notice\\\":true,\\\"calendar\\\":true,\\\"document\\\":false,\\\"im\\\":true,\\\"email\\\":true,\\\"contacts\\\":true,\\\"commission\\\":false,\\\"meetingCount\\\":true,\\\"interview\\\":true},\\\"userName\\\":\\\"test01\\\",\\\"realName\\\":\\\"测试1\\\",\\\"userKey\\\":\\\"会议报名\\\",\\\"password\\\":\\\"e10adc3949ba59abbe56e057f20f883e\\\",\\\"activitiSync\\\":1,\\\"status\\\":1,\\\"currentDepartId\\\":\\\"8a8afb90582942f501582944770d0028\\\",\\\"currentDepartName\\\":\\\"文电处\\\",\\\"id\\\":\\\"40287d81585174ba0158523e3db20010\\\"}"; - byte[] data = inputStr.getBytes(); - - byte[] encodedData = RSAUtilV2.encryptByPublicKey(data, publicKey); - - String enconde = Base64.encodeToString(encodedData, Base64.DEFAULT); - - - - byte[] decodedData = RSAUtilV2.decryptByPrivateKey(Base64.decode(enconde, Base64.DEFAULT), - privateKey); - - String outputStr = new String(decodedData); - System.out.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr); - } - - public static void test2() throws Exception - { - Map keyMap = RSACoder.initKey(); - - String publicKey = RSACoder.getPublicKey(keyMap); - String privateKey = RSACoder.getPrivateKey(keyMap); - - System.out.println("公钥:\n" + publicKey); - System.out.println("私钥:\n" + privateKey); - - System.err.println("私钥加密——公钥解密"); - String inputStr = "sign"; - byte[] data = inputStr.getBytes(); - - byte[] encodedData = RSACoder.encryptByPrivateKey(data, privateKey); - - byte[] decodedData = RSACoder - .decryptByPublicKey(encodedData, publicKey); - - String outputStr = new String(decodedData); - System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr); - - - System.err.println("私钥签名——公钥验证签名"); - // 产生签名 - String sign = RSACoder.sign(encodedData, privateKey); - System.err.println("签名:\r" + sign); - - // 验证签名 - boolean status = RSACoder.verify(encodedData, publicKey, sign); - System.err.println("状态:\r" + status); - - } - - /* public static void main(String[] args) throws Exception { - - - //test2(); - test(); - }*/ -} \ No newline at end of file diff --git a/app/src/main/java/xyz/fycz/myreader/util/RSAUtilV2.java b/app/src/main/java/xyz/fycz/myreader/util/RSAUtilV2.java deleted file mode 100644 index bfaf807..0000000 --- a/app/src/main/java/xyz/fycz/myreader/util/RSAUtilV2.java +++ /dev/null @@ -1,478 +0,0 @@ -package xyz.fycz.myreader.util; - -/** - * Created by zhao on 2017/1/20. - */ - - -import java.io.ByteArrayOutputStream; -import java.security.Key; -import java.security.KeyFactory; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.Signature; -import java.security.interfaces.RSAPrivateKey; -import java.security.interfaces.RSAPublicKey; -import java.security.spec.PKCS8EncodedKeySpec; -import java.security.spec.X509EncodedKeySpec; -import java.util.HashMap; -import java.util.Map; - -import javax.crypto.Cipher; - - - -/** */ - -/** - *

- * RSA公钥/私钥/签名工具包 v2 UPDATE BY ZYL - *

- *

- * 罗纳德·李维斯特(Ron [R]ivest)、阿迪·萨莫尔(Adi [S]hamir)和伦纳德·阿德曼(Leonard [A]dleman) - *

- *

- * 字符串格式的密钥在未在特殊说明情况下都为BASE64编码格式
- * 由于非对称加密速度极其缓慢,一般文件不使用它来加密而是使用对称加密,
- * 非对称加密算法可以用来对对称加密的密钥加密,这样保证密钥的安全也就保证了数据的安全 - *

- *

- * 版本2更新变化: - * 1原版本密钥创建后保存在内存map中,新版本密钥创建后保存为public.key,private.key的功能(base64解码后保存). - * 2为保证生成文件的密钥内容可以显示并缩短加密后的长度,对需加密内容进行hex(16进制转换)处理后再加密. - * 即 - *

- * - * @author IceWee - * @version 1.0 - * @date 2012-4-26 - */ -public class RSAUtilV2 extends Coder { - - /** */ - /** - * 加密算法RSA - */ - public static final String KEY_ALGORITHM = "RSA"; - - /** */ - /** - * 签名算法 - */ - public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; - - /** */ - /** - * 获取公钥的key - */ - private static final String PUBLIC_KEY = "RSAPublicKey"; - - /** */ - /** - * 获取私钥的key - */ - private static final String PRIVATE_KEY = "RSAPrivateKey"; - - /** */ - /** - * RSA最大加密明文大小 - */ - private static final int MAX_ENCRYPT_BLOCK = 117; - - /** */ - /** - * RSA最大解密密文大小 - */ - private static final int MAX_DECRYPT_BLOCK = 128; - - /** */ - /** - *

- * 生成密钥对(公钥和私钥) - *

- * - * @return - * @throws Exception - */ - public static Map genKeyPair() throws Exception { - KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);//"RSA" - keyPairGen.initialize(1024); - KeyPair keyPair = keyPairGen.generateKeyPair();//Generates a key pair 生成公钥私钥. - RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();//取得公钥 - RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();//取得私钥 - Map keyMap = new HashMap(2); - keyMap.put(PUBLIC_KEY, publicKey); - keyMap.put(PRIVATE_KEY, privateKey); - return keyMap; - } - - /** - * 将公钥私钥(默认base64加密)并转为公钥/私钥字符串还原为对应公钥/私钥 - * by Z10 - * - * @param keyType (publicKey / privateKey) - * @param keystr - * @return - * @throws Exception - */ - public Key getKeybyKeyStr(String keyType, String keystr) throws Exception { - if (keyType == null || !keyType.equals("")) { - throw new Exception("keyType can not be null"); - } - //需要返回公钥 - if (keyType.equals(keyType)) { - byte[] keyBytes = decryptBASE64(keystr); - X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); - KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); - Key publicK = keyFactory.generatePublic(x509KeySpec); - return publicK; - } - //需要返回私钥 - else if (keyType.equals("privateKey")) { - byte[] keyBytes = decryptBASE64(keystr); - PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); - KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); - Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); - return privateK; - } else { - throw new Exception("keyType'value is incorrect"); - } - } - - - - /** */ - /** - *

- * 用私钥对信息生成数字签名 - *

- * - * @param data 已加密数据 - * @param privateKey 私钥(BASE64编码) - * @return - * @throws Exception - */ - public static String sign(byte[] data, String privateKey) throws Exception { - byte[] keyBytes = decryptBASE64(privateKey); - PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); - KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); - PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec); - Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); - signature.initSign(privateK); - signature.update(data); - return encryptBASE64(signature.sign()); - } - - /** */ - /** - * 校验数字签名 - *

- * - * @param data 已加密数据 - * @param publicKey 公钥(BASE64编码) - * @param sign 数字签名 - * @return - * @throws Exception - */ - public static boolean verify(byte[] data, String publicKey, String sign) - throws Exception { - byte[] keyBytes = decryptBASE64(publicKey); - X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); - KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); - PublicKey publicK = keyFactory.generatePublic(keySpec); - Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); - signature.initVerify(publicK); - signature.update(data); - return signature.verify(decryptBASE64(sign)); - } - - - /** - * 私钥解密 by zyl - */ - public static byte[] decryptByPrivateKey(byte[] encryptedData, Key privateKey) throws Exception { - Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); - cipher.init(Cipher.DECRYPT_MODE, privateKey); - int inputLen = encryptedData.length; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - int offSet = 0; - byte[] cache; - int i = 0; - // 对数据分段解密 - while (inputLen - offSet > 0) { - if (inputLen - offSet > MAX_DECRYPT_BLOCK) { - cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); - } else { - cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet); - } - out.write(cache, 0, cache.length); - i++; - offSet = i * MAX_DECRYPT_BLOCK; - } - byte[] decryptedData = out.toByteArray(); - out.close(); - return decryptedData; - } - - /** */ - /** - * 私钥解密 - *

- * - * @param encryptedData 已加密数据 - * @param privateKey 私钥(BASE64编码) - * @return - * @throws Exception - */ - public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) - throws Exception { - byte[] keyBytes = decryptBASE64(privateKey); - PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); - KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); - Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); - Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); - cipher.init(Cipher.DECRYPT_MODE, privateK); - int inputLen = encryptedData.length; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - int offSet = 0; - byte[] cache; - int i = 0; - // 对数据分段解密 - while (inputLen - offSet > 0) { - if (inputLen - offSet > MAX_DECRYPT_BLOCK) { - cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); - } else { - cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet); - } - out.write(cache, 0, cache.length); - i++; - offSet = i * MAX_DECRYPT_BLOCK; - } - byte[] decryptedData = out.toByteArray(); - out.close(); - return decryptedData; - } - - - /** */ - /** - * 公钥解密 - *

- * - * @param encryptedData 已加密数据 - * @param publicKey 公钥(BASE64编码) - * @return - * @throws Exception - */ - public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey) - throws Exception { - - byte[] keyBytes = decryptBASE64(publicKey); - X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); - KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); - Key publicK = keyFactory.generatePublic(x509KeySpec); - Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); - cipher.init(Cipher.DECRYPT_MODE, publicK); - int inputLen = encryptedData.length; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - int offSet = 0; - byte[] cache; - int i = 0; - // 对数据分段解密 - while (inputLen - offSet > 0) { - if (inputLen - offSet > MAX_DECRYPT_BLOCK) { - cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); - } else { - cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet); - } - out.write(cache, 0, cache.length); - i++; - offSet = i * MAX_DECRYPT_BLOCK; - } - byte[] decryptedData = out.toByteArray(); - out.close(); - return decryptedData; - } - - /** - * 公钥加密 by zyl - * - * @param data - * @param publicKey - * @return - */ - public static byte[] encryptByPublicKey(byte[] data, Key publicKey) throws Exception { - // 对数据加密 - /*根据公钥加密*/ - Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); - cipher.init(Cipher.ENCRYPT_MODE, publicKey); - int inputLen = data.length; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - int offSet = 0; - byte[] cache; - int i = 0; - // 对数据分段加密 - while (inputLen - offSet > 0) { - if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { - cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); - } else { - cache = cipher.doFinal(data, offSet, inputLen - offSet); - } - out.write(cache, 0, cache.length); - i++; - offSet = i * MAX_ENCRYPT_BLOCK; - } - byte[] encryptedData = out.toByteArray(); - out.close(); - return encryptedData; - } - - /** - *

- * 公钥加密 - *

- * - * @param data 源数据 - * @param publicKey 公钥(BASE64编码) - * @return - * @throws Exception - */ - public static byte[] encryptByPublicKey(byte[] data, String publicKey) - throws Exception { - byte[] keyBytes = decryptBASE64(publicKey); - X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); - KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); - Key publicK = keyFactory.generatePublic(x509KeySpec); - // 对数据加密 - Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); - cipher.init(Cipher.ENCRYPT_MODE, publicK); - int inputLen = data.length; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - int offSet = 0; - byte[] cache; - int i = 0; - // 对数据分段加密 - while (inputLen - offSet > 0) { - if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { - cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); - } else { - cache = cipher.doFinal(data, offSet, inputLen - offSet); - } - out.write(cache, 0, cache.length); - i++; - offSet = i * MAX_ENCRYPT_BLOCK; - } - byte[] encryptedData = out.toByteArray(); - out.close(); - return encryptedData; - } - - /** - * 私钥加密by zyl - */ - public static byte[] encryptByPrivateKey(byte[] data, Key privateKey) throws Exception { - Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); - cipher.init(Cipher.ENCRYPT_MODE, privateKey); - int inputLen = data.length; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - int offSet = 0; - byte[] cache; - int i = 0; - // 对数据分段加密 - while (inputLen - offSet > 0) { - if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { - cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); - } else { - cache = cipher.doFinal(data, offSet, inputLen - offSet); - } - out.write(cache, 0, cache.length); - i++; - offSet = i * MAX_ENCRYPT_BLOCK; - } - byte[] encryptedData = out.toByteArray(); - out.close(); - return encryptedData; - } - - - /** */ - /** - *

- * 私钥加密 - *

- * - * @param data 源数据 - * @param privateKey 私钥(BASE64编码) - * @return - * @throws Exception - */ - public static byte[] encryptByPrivateKey(byte[] data, String privateKey) - throws Exception { - byte[] keyBytes = decryptBASE64(privateKey); - PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); - KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); - Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); - Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); - cipher.init(Cipher.ENCRYPT_MODE, privateK); - int inputLen = data.length; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - int offSet = 0; - byte[] cache; - int i = 0; - // 对数据分段加密 - while (inputLen - offSet > 0) { - if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { - cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); - } else { - cache = cipher.doFinal(data, offSet, inputLen - offSet); - } - out.write(cache, 0, cache.length); - i++; - offSet = i * MAX_ENCRYPT_BLOCK; - } - byte[] encryptedData = out.toByteArray(); - out.close(); - return encryptedData; - } - - /** */ - /** - *

- * 获取私钥 - *

- * - * @param keyMap 密钥对 - * @return - * @throws Exception - */ - public static String getPrivateKey(Map keyMap) - throws Exception { - Key key = (Key) keyMap.get(PRIVATE_KEY); - return encryptBASE64(key.getEncoded()); - } - - /** */ - /** - *

- * 获取公钥 - *

- * - * @param keyMap 密钥对 - * @return - * @throws Exception - */ - public static String getPublicKey(Map keyMap) - throws Exception { - Key key = (Key) keyMap.get(PUBLIC_KEY); - return encryptBASE64(key.getEncoded()); - } - - /* public static void main(String[] args) throws Exception { - - - //test2(); - test(); - }*/ -} diff --git a/app/src/main/java/xyz/fycz/myreader/util/SSLSocketClient.java b/app/src/main/java/xyz/fycz/myreader/util/SSLSocketClient.java new file mode 100644 index 0000000..5e93411 --- /dev/null +++ b/app/src/main/java/xyz/fycz/myreader/util/SSLSocketClient.java @@ -0,0 +1,118 @@ +package xyz.fycz.myreader.util; + +import android.annotation.SuppressLint; +import android.graphics.Bitmap; +import android.util.Base64; +import android.util.Log; + +import com.google.gson.Gson; +import okhttp3.*; +import xyz.fycz.myreader.R; +import xyz.fycz.myreader.application.App; +import xyz.fycz.myreader.webapi.callback.HttpCallback; +import xyz.fycz.myreader.webapi.callback.JsonCallback; +import xyz.fycz.myreader.webapi.callback.URLConnectionCallback; +import xyz.fycz.myreader.common.APPCONST; +import xyz.fycz.myreader.common.URLCONST; +import xyz.fycz.myreader.entity.JsonModel; + +import java.io.*; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.security.SecureRandom; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.*; +import java.util.concurrent.TimeUnit; + +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import static java.lang.String.valueOf; + + +public class SSLSocketClient { + + public static SSLSocketFactory createSSLSocketFactory() { + SSLSocketFactory ssfFactory = null; + try { + SSLContext sc = SSLContext.getInstance("TLS"); + sc.init(null, new TrustManager[]{createTrustAllManager()}, new SecureRandom()); + ssfFactory = sc.getSocketFactory(); + } catch (Exception e) { + } + + return ssfFactory; + } + + public static X509TrustManager createTrustAllManager() { + X509TrustManager tm = null; + try { + tm = new X509TrustManager() { + @SuppressLint("TrustAllX509TrustManager") + public void checkClientTrusted(X509Certificate[] chain, String authType) { + //do nothing,接受任意客户端证书 + } + + @SuppressLint("TrustAllX509TrustManager") + public void checkServerTrusted(X509Certificate[] chain, String authType) { + //do nothing,接受任意服务端证书 + } + + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } + }; + } catch (Exception ignored) { + } + return tm; + } + + public static Interceptor getHeaderInterceptor() { + return chain -> { + Request request = chain.request() + .newBuilder() + .addHeader("Keep-Alive", "300") + .addHeader("Connection", "Keep-Alive") + .addHeader("Cache-Control", "no-cache") + .build(); + return chain.proceed(request); + }; + } + + /** + * Trust every server - dont check for any certificate + */ + public static void trustAllHosts() { + final String TAG = "trustAllHosts"; + // Create a trust manager that does not validate certificate chains + TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() { + + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return new java.security.cert.X509Certificate[]{}; + } + + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + Log.i(TAG, "checkClientTrusted"); + } + + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + Log.i(TAG, "checkServerTrusted"); + } + }}; + + // Install the all-trusting trust manager + try { + SSLContext sc = SSLContext.getInstance("TLS"); + sc.init(null, trustAllCerts, new java.security.SecureRandom()); + HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/app/src/main/java/xyz/fycz/myreader/util/utils/JsExtensions.java b/app/src/main/java/xyz/fycz/myreader/util/utils/JsExtensions.java index e60ec59..6377867 100644 --- a/app/src/main/java/xyz/fycz/myreader/util/utils/JsExtensions.java +++ b/app/src/main/java/xyz/fycz/myreader/util/utils/JsExtensions.java @@ -9,8 +9,7 @@ import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; -import xyz.fycz.myreader.model.analyzeRule.AnalyzeUrl; -import xyz.fycz.myreader.util.HttpUtil; +import xyz.fycz.myreader.util.SSLSocketClient; @SuppressWarnings({"unused", "WeakerAccess"}) public interface JsExtensions { @@ -56,7 +55,7 @@ public interface JsExtensions { */ default Connection.Response get(String urlStr, Map headers) throws IOException { return Jsoup.connect(urlStr) - .sslSocketFactory(HttpUtil.createSSLSocketFactory()) + .sslSocketFactory(SSLSocketClient.createSSLSocketFactory()) .ignoreContentType(true) .followRedirects(false) .headers(headers) @@ -69,7 +68,7 @@ public interface JsExtensions { */ default Connection.Response post(String urlStr, String body, Map headers) throws IOException { return Jsoup.connect(urlStr) - .sslSocketFactory(HttpUtil.createSSLSocketFactory()) + .sslSocketFactory(SSLSocketClient.createSSLSocketFactory()) .ignoreContentType(true) .followRedirects(false) .requestBody(body) diff --git a/app/src/main/java/xyz/fycz/myreader/util/utils/OkHttpUtils.java b/app/src/main/java/xyz/fycz/myreader/util/utils/OkHttpUtils.java index 16d99f7..e09d96a 100644 --- a/app/src/main/java/xyz/fycz/myreader/util/utils/OkHttpUtils.java +++ b/app/src/main/java/xyz/fycz/myreader/util/utils/OkHttpUtils.java @@ -9,16 +9,37 @@ import org.jsoup.nodes.Document; import okhttp3.*; import xyz.fycz.myreader.application.App; -import xyz.fycz.myreader.util.HttpUtil; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; +import java.util.Collections; import java.util.Map; +import java.util.concurrent.TimeUnit; + +import static xyz.fycz.myreader.util.SSLSocketClient.createSSLSocketFactory; +import static xyz.fycz.myreader.util.SSLSocketClient.createTrustAllManager; +import static xyz.fycz.myreader.util.SSLSocketClient.getHeaderInterceptor; public class OkHttpUtils { - public static OkHttpClient okHttpClient = HttpUtil.getOkHttpClient(); + public static OkHttpClient mClient; + + public static synchronized OkHttpClient getOkHttpClient() { + if (mClient == null) { + OkHttpClient.Builder builder = new OkHttpClient.Builder(); + builder.connectTimeout(5, TimeUnit.SECONDS) + .readTimeout(10, TimeUnit.SECONDS) + .writeTimeout(10, TimeUnit.SECONDS) + .sslSocketFactory(createSSLSocketFactory(), createTrustAllManager()) + .hostnameVerifier((hostname, session) -> true) + .protocols(Collections.singletonList(Protocol.HTTP_1_1)) + .addInterceptor(getHeaderInterceptor()); + mClient = builder + .build(); + } + return mClient; + } /** * 同步获取html文件,默认编码utf-8 @@ -44,7 +65,7 @@ public class OkHttpUtils { .addHeader("Cache-Control", "no-cache") .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36"); if (headers != null) { - for (String name : headers.keySet()){ + for (String name : headers.keySet()) { builder.addHeader(name, headers.get(name)); } } @@ -57,7 +78,7 @@ public class OkHttpUtils { Request request = builder .url(url) .build(); - Response response = okHttpClient + Response response = getOkHttpClient() .newCall(request) .execute(); ResponseBody body = response.body(); @@ -76,7 +97,7 @@ public class OkHttpUtils { Request request = builder .url(url) .build(); - Response response = okHttpClient + Response response = getOkHttpClient() .newCall(request) .execute(); if (response.body() == null) { @@ -99,7 +120,7 @@ public class OkHttpUtils { Request request = builder .url(url) .build(); - Response response = okHttpClient + Response response = getOkHttpClient() .newCall(request) .execute(); ResponseBody body = response.body(); diff --git a/app/src/main/java/xyz/fycz/myreader/util/webdav/WebDav.kt b/app/src/main/java/xyz/fycz/myreader/util/webdav/WebDav.kt index d6fbee4..f1ae186 100644 --- a/app/src/main/java/xyz/fycz/myreader/util/webdav/WebDav.kt +++ b/app/src/main/java/xyz/fycz/myreader/util/webdav/WebDav.kt @@ -4,7 +4,8 @@ import xyz.fycz.myreader.util.webdav.http.Handler import xyz.fycz.myreader.util.webdav.http.HttpAuth import okhttp3.* import org.jsoup.Jsoup -import xyz.fycz.myreader.util.HttpUtil +import xyz.fycz.myreader.util.SSLSocketClient +import xyz.fycz.myreader.util.utils.OkHttpUtils import java.io.File import java.io.IOException import java.io.InputStream @@ -131,7 +132,7 @@ constructor(urlStr: String) { ) } request.header("Depth", if (depth < 0) "infinity" else depth.toString()) - return HttpUtil.getOkHttpClient().newCall(request.build()).execute() + return OkHttpUtils.getOkHttpClient().newCall(request.build()).execute() } return null } @@ -226,7 +227,7 @@ constructor(urlStr: String) { Credentials.basic(it.user, it.pass) ) } - val response = HttpUtil.getOkHttpClient().newCall(requestBuilder.build()).execute() + val response = OkHttpUtils.getOkHttpClient().newCall(requestBuilder.build()).execute() return response.isSuccessful } @@ -237,7 +238,7 @@ constructor(urlStr: String) { request.header("Authorization", Credentials.basic(it.user, it.pass)) } try { - return HttpUtil.getOkHttpClient().newCall(request.build()).execute().body()?.byteStream() + return OkHttpUtils.getOkHttpClient().newCall(request.build()).execute().body()?.byteStream() } catch (e: IOException) { e.printStackTrace() } catch (e: IllegalArgumentException) { diff --git a/app/src/main/java/xyz/fycz/myreader/webapi/HttpDataSource.java b/app/src/main/java/xyz/fycz/myreader/webapi/HttpDataSource.java deleted file mode 100644 index 623e800..0000000 --- a/app/src/main/java/xyz/fycz/myreader/webapi/HttpDataSource.java +++ /dev/null @@ -1,125 +0,0 @@ -package xyz.fycz.myreader.webapi; - -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.util.Base64; -import android.util.Log; - -import xyz.fycz.myreader.webapi.callback.JsonCallback; -import xyz.fycz.myreader.common.APPCONST; -import xyz.fycz.myreader.common.URLCONST; -import xyz.fycz.myreader.entity.JsonModel; -import xyz.fycz.myreader.util.HttpUtil; -import xyz.fycz.myreader.util.RSAUtilV2; -import xyz.fycz.myreader.util.StringHelper; -import com.google.gson.Gson; -import xyz.fycz.myreader.webapi.callback.HttpCallback; -import xyz.fycz.myreader.webapi.callback.ResultCallback; - -import java.io.BufferedReader; -import java.io.File; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.Map; - - -public class HttpDataSource { - - /** - * http请求 (get) ps:获取html - * @param url - * @param callback - */ - public static void httpGet_html(String url, final String charsetName, boolean isRefresh, final ResultCallback callback){ - Log.d("HttpGet URl", url); - HttpUtil.sendGetRequest_okHttp(url, isRefresh, new HttpCallback() { - @Override - public void onFinish(Bitmap bm) { - - } - - @Override - public void onFinish(InputStream in) { - try { - BufferedReader reader = new BufferedReader(new InputStreamReader(in, charsetName)); - StringBuilder response = new StringBuilder(); - String line = reader.readLine(); - while (line != null) { - response.append(line); - line = reader.readLine(); - } - if (callback != null) { - Log.d("Http", "read finish:" + response.toString()); - callback.onFinish(response.toString(),0); - } - } catch (Exception e) { - callback.onError(e); - } - } - - @Override - public void onFinish(String response) { - Log.d("Local", "read finish:" + response); - callback.onFinish(response, 0); - } - - @Override - public void onError(Exception e) { - if (callback != null) { - callback.onError(e); - } - } - - }); - } - - - - /** - * http请求 (post) 获取蓝奏云直链 - * @param url - * @param output - * @param callback - */ - public static void httpPost(String url, String output, final ResultCallback callback, final String referer) { - Log.d("HttpPost:", url + "&" + output); - HttpUtil.sendPostRequest(url, output, new HttpCallback() { - @Override - public void onFinish(Bitmap bm) { - - } - @Override - public void onFinish(InputStream in) { - try { - BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8")); - StringBuilder response = new StringBuilder(); - String line = reader.readLine(); - while (line != null) { - response.append(line); - line = reader.readLine(); - } - if (callback != null) { - Log.d("Http", "read finish:" + response); - callback.onFinish(response.toString(), 1); - } - } catch (Exception e) { - callback.onError(e); - } - } - - @Override - public void onFinish(String response) { - Log.e("http", response); - } - - @Override - public void onError(Exception e) { - if (callback != null) { - callback.onError(e); - } - } - }, referer); - } - -} diff --git a/app/src/main/java/xyz/fycz/myreader/widget/page/PageLoader.java b/app/src/main/java/xyz/fycz/myreader/widget/page/PageLoader.java index 79026d7..6ba81ee 100644 --- a/app/src/main/java/xyz/fycz/myreader/widget/page/PageLoader.java +++ b/app/src/main/java/xyz/fycz/myreader/widget/page/PageLoader.java @@ -1673,7 +1673,7 @@ public abstract class PageLoader { } // 重置段落 if (!showTitle) { - paragraph = paragraph.replaceAll("[ | ]", " ").trim(); + paragraph = StringUtils.trim(paragraph); // 如果只有换行符,那么就不执行 if (paragraph.equals("")) continue; paragraph = indent + paragraph + "\n";