From b5f914e010ba0999079e4e444c351b1672c996d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=94=90=E4=B8=89?= <89683694+Tangsan99999@users.noreply.github.com> Date: Tue, 11 Oct 2022 15:38:07 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E9=85=8D=E5=90=88=E4=BD=BF=E7=94=A8=20http?= =?UTF-8?q?s://catvodtvofficial.github.io/CatVodTVJsonEditor/?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/fongmi/android/tv/api/ApiConfig.java | 83 +++++++++++++++++-- .../java/com/fongmi/android/tv/utils/AES.java | 77 +++++++++++++++++ 2 files changed, 155 insertions(+), 5 deletions(-) create mode 100644 app/src/main/java/com/fongmi/android/tv/utils/AES.java diff --git a/app/src/main/java/com/fongmi/android/tv/api/ApiConfig.java b/app/src/main/java/com/fongmi/android/tv/api/ApiConfig.java index a2471211a..7199ab556 100644 --- a/app/src/main/java/com/fongmi/android/tv/api/ApiConfig.java +++ b/app/src/main/java/com/fongmi/android/tv/api/ApiConfig.java @@ -3,6 +3,7 @@ package com.fongmi.android.tv.api; import android.os.Handler; import android.os.Looper; import android.text.TextUtils; +import android.util.Base64; import com.fongmi.android.tv.R; import com.fongmi.android.tv.bean.Config; @@ -11,6 +12,7 @@ import com.fongmi.android.tv.bean.Parse; import com.fongmi.android.tv.bean.Site; import com.fongmi.android.tv.net.Callback; import com.fongmi.android.tv.net.OKHttp; +import com.fongmi.android.tv.utils.AES; import com.fongmi.android.tv.utils.FileUtil; import com.fongmi.android.tv.utils.Json; import com.fongmi.android.tv.utils.Prefers; @@ -24,6 +26,7 @@ import com.google.gson.stream.JsonReader; import org.json.JSONObject; +import java.io.BufferedReader; import java.io.FileReader; import java.util.ArrayList; import java.util.Collections; @@ -86,14 +89,83 @@ public class ApiConfig { public void loadConfig(boolean cache, Callback callback) { new Thread(() -> { - String url = Prefers.getUrl(); + String url = Prefers.getUrl(), pk = ";pk;"; if (cache) getCacheConfig(url, callback); - else if (url.startsWith("http")) getWebConfig(url, callback); - else if (url.startsWith("file")) getFileConfig(url, callback); - else handler.post(() -> callback.error(0)); + else if (url.contains(pk)) { + String[] a = url.split(pk); + if (url.startsWith("http")) decryptWebConfig(a[0], callback, a[1]); + if (url.startsWith("file")) decryptFileConfig(a[0], callback, a[1]); + } else if (!url.contains(pk)) { + if (url.startsWith("http")) decryptWebConfig(url, callback, null); + if (url.startsWith("file")) decryptFileConfig(url, callback, null); + } else handler.post(() -> callback.error(0)); }).start(); } + private void decryptFileConfig(String url, Callback callback, String FinalKey) { + try { + String content = "", json = "", line = null, ls = System.getProperty("line.separator"); + BufferedReader read = new BufferedReader(new FileReader(FileUtil.getLocal(url))); + StringBuilder text = new StringBuilder(); + while ((line = read.readLine()) != null) { + text.append(line); + text.append(ls); + } + text.deleteCharAt(text.length() - 1); + read.close(); + String reader = text.toString(); + if (AES.isJson(reader)) { + getFileConfig(reader, callback); + return; + } else if (!reader.startsWith("2423")) { + content = new String(Base64.decode(reader.split("\\*\\*")[1], Base64.DEFAULT)); + } else { + content = reader; + } + if (content.startsWith("2423")) { + String data2 = content.substring(content.indexOf("2324") + 4, content.length() - 26); + content = new String(AES.toBytes(content)).toLowerCase(); + String key = AES.rightPading(content.substring(content.indexOf("$#") + 2, content.indexOf("#$")), "0", 16); + String iv = AES.rightPading(content.substring(content.length() - 13), "0", 16); + json = AES.CBC(data2, key, iv); + } else { + json = AES.ECB(content, FinalKey); + } + parseConfig(new Gson().fromJson(json, JsonObject.class), callback); + } catch (Exception e) { + e.printStackTrace(); + handler.post(() -> callback.error(R.string.error_config_get)); + } + } + + private void decryptWebConfig(String url, Callback callback, String FinalKey) { + try { + String content = "", json = ""; + String reader = OKHttp.newCall(url).execute().body().string(); + if (AES.isJson(reader)) { + getWebConfig(reader, callback); + return; + } else if (!reader.startsWith("2423")) { + content = new String(Base64.decode(reader.split("\\*\\*")[1], Base64.DEFAULT)); + } else { + content = reader; + } + if (content.startsWith("2423")) { + String data2 = content.substring(content.indexOf("2324") + 4, content.length() - 26); + content = new String(AES.toBytes(content)).toLowerCase(); + String key = AES.rightPading(content.substring(content.indexOf("$#") + 2, content.indexOf("#$")), "0", 16); + String iv = AES.rightPading(content.substring(content.length() - 13), "0", 16); + json = AES.CBC(data2, key, iv); + } else { + json = AES.ECB(content, FinalKey); + } + parseConfig(new Gson().fromJson(json, JsonObject.class), callback); + } catch (Exception e) { + e.printStackTrace(); + handler.post(() -> callback.error(R.string.error_config_get)); + } + } + private void getFileConfig(String url, Callback callback) { try { parseConfig(new Gson().fromJson(new JsonReader(new FileReader(FileUtil.getLocal(url))), JsonObject.class), callback); @@ -114,7 +186,8 @@ public class ApiConfig { private void getCacheConfig(String url, Callback callback) { String json = Config.find(url).getJson(); - if (!TextUtils.isEmpty(json)) parseConfig(JsonParser.parseString(json).getAsJsonObject(), callback); + if (!TextUtils.isEmpty(json)) + parseConfig(JsonParser.parseString(json).getAsJsonObject(), callback); else handler.post(() -> callback.error(R.string.error_config_get)); } diff --git a/app/src/main/java/com/fongmi/android/tv/utils/AES.java b/app/src/main/java/com/fongmi/android/tv/utils/AES.java new file mode 100644 index 000000000..a3630e2a1 --- /dev/null +++ b/app/src/main/java/com/fongmi/android/tv/utils/AES.java @@ -0,0 +1,77 @@ +package com.fongmi.android.tv.utils; + +import com.github.catvod.crawler.SpiderDebug; + +import org.json.JSONObject; + +import java.security.spec.AlgorithmParameterSpec; + +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +public class AES { + + public static String rightPading(String key, String replace, int Length) { + String strReturn = ""; + String strtemp = ""; + int curLength = key.trim().length(); + if (key != null && curLength > Length) { + strReturn = key.trim().substring(0, Length); + } else if (key != null && curLength == Length) { + strReturn = key.trim(); + } else { + for (int i = 0; i < (Length - curLength); i++) { + strtemp = strtemp + replace; + } + strReturn = key.trim() + strtemp; + } + return strReturn; + } + + public static String ECB(String data, String key) { + try { + key = rightPading(key, "0", 16); + byte[] data2 = toBytes(data); + SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "AES"); + Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding"); + cipher.init(Cipher.DECRYPT_MODE, keySpec); + return new String(cipher.doFinal(data2)); + } catch (Exception exception) { + SpiderDebug.log(exception); + } + return null; + } + + public static String CBC(String src, String KEY, String IV) { + try { + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); + SecretKeySpec keySpec = new SecretKeySpec(KEY.getBytes(), "AES"); + AlgorithmParameterSpec paramSpec = new IvParameterSpec(IV.getBytes()); + cipher.init(Cipher.DECRYPT_MODE, keySpec, paramSpec); + return new String(cipher.doFinal(toBytes(src))); + } catch (Exception exception) { + SpiderDebug.log(exception); + } + return null; + } + + public static byte[] toBytes(String src) { + int l = src.length() / 2; + byte[] ret = new byte[l]; + for (int i = 0; i < l; i++) { + ret[i] = Integer.valueOf(src.substring(i * 2, i * 2 + 2), 16).byteValue(); + } + return ret; + } + + public static boolean isJson(String content) { + try { + new JSONObject(content); + return true; + } catch (Exception e) { + return false; + } + } + +} From 8aad7c86bb4463dc17f808a25d2a75da7c8c0078 Mon Sep 17 00:00:00 2001 From: FongMi Date: Tue, 11 Oct 2022 19:28:58 +0800 Subject: [PATCH 2/5] Clean code --- .../com/fongmi/android/tv/api/ApiConfig.java | 106 ++---------------- .../com/fongmi/android/tv/api/Decoder.java | 72 ++++++++++++ .../com/fongmi/android/tv/utils/FileUtil.java | 3 +- .../com/fongmi/android/tv/utils/Json.java | 11 ++ .../com/fongmi/android/tv/utils/Utils.java | 6 +- 5 files changed, 96 insertions(+), 102 deletions(-) create mode 100644 app/src/main/java/com/fongmi/android/tv/api/Decoder.java diff --git a/app/src/main/java/com/fongmi/android/tv/api/ApiConfig.java b/app/src/main/java/com/fongmi/android/tv/api/ApiConfig.java index 7199ab556..b6a8c663e 100644 --- a/app/src/main/java/com/fongmi/android/tv/api/ApiConfig.java +++ b/app/src/main/java/com/fongmi/android/tv/api/ApiConfig.java @@ -3,7 +3,6 @@ package com.fongmi.android.tv.api; import android.os.Handler; import android.os.Looper; import android.text.TextUtils; -import android.util.Base64; import com.fongmi.android.tv.R; import com.fongmi.android.tv.bean.Config; @@ -11,8 +10,6 @@ import com.fongmi.android.tv.bean.Live; import com.fongmi.android.tv.bean.Parse; import com.fongmi.android.tv.bean.Site; import com.fongmi.android.tv.net.Callback; -import com.fongmi.android.tv.net.OKHttp; -import com.fongmi.android.tv.utils.AES; import com.fongmi.android.tv.utils.FileUtil; import com.fongmi.android.tv.utils.Json; import com.fongmi.android.tv.utils.Prefers; @@ -22,12 +19,9 @@ import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; -import com.google.gson.stream.JsonReader; import org.json.JSONObject; -import java.io.BufferedReader; -import java.io.FileReader; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -89,108 +83,26 @@ public class ApiConfig { public void loadConfig(boolean cache, Callback callback) { new Thread(() -> { - String url = Prefers.getUrl(), pk = ";pk;"; - if (cache) getCacheConfig(url, callback); - else if (url.contains(pk)) { - String[] a = url.split(pk); - if (url.startsWith("http")) decryptWebConfig(a[0], callback, a[1]); - if (url.startsWith("file")) decryptFileConfig(a[0], callback, a[1]); - } else if (!url.contains(pk)) { - if (url.startsWith("http")) decryptWebConfig(url, callback, null); - if (url.startsWith("file")) decryptFileConfig(url, callback, null); - } else handler.post(() -> callback.error(0)); + if (cache) loadCache(Prefers.getUrl(), callback); + else loadJson(Prefers.getUrl(), callback); }).start(); } - private void decryptFileConfig(String url, Callback callback, String FinalKey) { - try { - String content = "", json = "", line = null, ls = System.getProperty("line.separator"); - BufferedReader read = new BufferedReader(new FileReader(FileUtil.getLocal(url))); - StringBuilder text = new StringBuilder(); - while ((line = read.readLine()) != null) { - text.append(line); - text.append(ls); - } - text.deleteCharAt(text.length() - 1); - read.close(); - String reader = text.toString(); - if (AES.isJson(reader)) { - getFileConfig(reader, callback); - return; - } else if (!reader.startsWith("2423")) { - content = new String(Base64.decode(reader.split("\\*\\*")[1], Base64.DEFAULT)); - } else { - content = reader; - } - if (content.startsWith("2423")) { - String data2 = content.substring(content.indexOf("2324") + 4, content.length() - 26); - content = new String(AES.toBytes(content)).toLowerCase(); - String key = AES.rightPading(content.substring(content.indexOf("$#") + 2, content.indexOf("#$")), "0", 16); - String iv = AES.rightPading(content.substring(content.length() - 13), "0", 16); - json = AES.CBC(data2, key, iv); - } else { - json = AES.ECB(content, FinalKey); - } - parseConfig(new Gson().fromJson(json, JsonObject.class), callback); - } catch (Exception e) { - e.printStackTrace(); - handler.post(() -> callback.error(R.string.error_config_get)); - } - } - - private void decryptWebConfig(String url, Callback callback, String FinalKey) { - try { - String content = "", json = ""; - String reader = OKHttp.newCall(url).execute().body().string(); - if (AES.isJson(reader)) { - getWebConfig(reader, callback); - return; - } else if (!reader.startsWith("2423")) { - content = new String(Base64.decode(reader.split("\\*\\*")[1], Base64.DEFAULT)); - } else { - content = reader; - } - if (content.startsWith("2423")) { - String data2 = content.substring(content.indexOf("2324") + 4, content.length() - 26); - content = new String(AES.toBytes(content)).toLowerCase(); - String key = AES.rightPading(content.substring(content.indexOf("$#") + 2, content.indexOf("#$")), "0", 16); - String iv = AES.rightPading(content.substring(content.length() - 13), "0", 16); - json = AES.CBC(data2, key, iv); - } else { - json = AES.ECB(content, FinalKey); - } - parseConfig(new Gson().fromJson(json, JsonObject.class), callback); - } catch (Exception e) { - e.printStackTrace(); - handler.post(() -> callback.error(R.string.error_config_get)); - } - } - - private void getFileConfig(String url, Callback callback) { - try { - parseConfig(new Gson().fromJson(new JsonReader(new FileReader(FileUtil.getLocal(url))), JsonObject.class), callback); - } catch (Exception e) { - e.printStackTrace(); - getCacheConfig(url, callback); - } + private void loadCache(String url, Callback callback) { + String json = Config.find(url).getJson(); + if (!TextUtils.isEmpty(json)) parseConfig(JsonParser.parseString(json).getAsJsonObject(), callback); + else handler.post(() -> callback.error(R.string.error_config_get)); } - private void getWebConfig(String url, Callback callback) { + private void loadJson(String url, Callback callback) { try { - parseConfig(new Gson().fromJson(OKHttp.newCall(url).execute().body().string(), JsonObject.class), callback); + parseConfig(new Gson().fromJson(Decoder.getJson(url), JsonObject.class), callback); } catch (Exception e) { e.printStackTrace(); - getCacheConfig(url, callback); + loadCache(url, callback); } } - private void getCacheConfig(String url, Callback callback) { - String json = Config.find(url).getJson(); - if (!TextUtils.isEmpty(json)) - parseConfig(JsonParser.parseString(json).getAsJsonObject(), callback); - else handler.post(() -> callback.error(R.string.error_config_get)); - } - private void parseConfig(JsonObject object, Callback callback) { try { parseJson(object); diff --git a/app/src/main/java/com/fongmi/android/tv/api/Decoder.java b/app/src/main/java/com/fongmi/android/tv/api/Decoder.java new file mode 100644 index 000000000..26f74a973 --- /dev/null +++ b/app/src/main/java/com/fongmi/android/tv/api/Decoder.java @@ -0,0 +1,72 @@ +package com.fongmi.android.tv.api; + +import android.util.Base64; + +import com.fongmi.android.tv.net.OKHttp; +import com.fongmi.android.tv.utils.FileUtil; +import com.fongmi.android.tv.utils.Json; + +import java.nio.charset.StandardCharsets; + +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +public class Decoder { + + public static String getJson(String url) throws Exception { + String key = url.contains(";") ? url.split(";")[2] : ""; + url = url.contains(";") ? url.split(";")[0] : url; + String data = getData(url); + if (Json.valid(data)) return data; + if (key.length() > 0) return ecb(data, key); + if (data.contains("**")) data = base64(data); + if (data.startsWith("2423")) data = cbc(data); + return data.replace("###", ""); + } + + private static String getData(String url) throws Exception { + if (url.startsWith("http")) return OKHttp.newCall(url).execute().body().string(); + else if (url.startsWith("file")) return FileUtil.read(url); + throw new Exception(); + } + + private static String ecb(String data, String key) throws Exception { + SecretKeySpec spec = new SecretKeySpec(padEnd(key), "AES"); + Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); + cipher.init(Cipher.DECRYPT_MODE, spec); + return new String(cipher.doFinal(decodeHex(data)), StandardCharsets.UTF_8); + } + + private static String cbc(String data) throws Exception { + int indexKey = data.indexOf("2324") + 4; + String key = new String(decodeHex(data.substring(0, indexKey)), StandardCharsets.UTF_8); + key = key.replace("$#", "").replace("#$", ""); + int indexIv = data.length() - 26; + String iv = data.substring(indexIv).trim(); + iv = new String(decodeHex(iv), StandardCharsets.UTF_8); + SecretKeySpec keySpec = new SecretKeySpec(padEnd(key), "AES"); + IvParameterSpec ivSpec = new IvParameterSpec(padEnd(iv)); + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); + data = data.substring(indexKey, indexIv).trim(); + byte[] encryptDataBytes = decodeHex(data); + byte[] decryptData = cipher.doFinal(encryptDataBytes); + return new String(decryptData, StandardCharsets.UTF_8); + } + + private static String base64(String data) { + return new String(Base64.decode(data.substring(data.indexOf("**") + 2), Base64.DEFAULT)); + } + + private static byte[] padEnd(String key) { + return (key + "0000000000000000".substring(key.length())).getBytes(StandardCharsets.UTF_8); + } + + private static byte[] decodeHex(String s) { + int len = s.length(); + byte[] data = new byte[len / 2]; + for (int i = 0; i < len; i += 2) data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16)); + return data; + } +} diff --git a/app/src/main/java/com/fongmi/android/tv/utils/FileUtil.java b/app/src/main/java/com/fongmi/android/tv/utils/FileUtil.java index 2ff2e6428..22050b87b 100644 --- a/app/src/main/java/com/fongmi/android/tv/utils/FileUtil.java +++ b/app/src/main/java/com/fongmi/android/tv/utils/FileUtil.java @@ -86,9 +86,8 @@ public class FileUtil { int count; while ((count = fis.read(byteArray)) != -1) digest.update(byteArray, 0, count); fis.close(); - byte[] bytes = digest.digest(); StringBuilder sb = new StringBuilder(); - for (byte b : bytes) sb.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1)); + for (byte b : digest.digest()) sb.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1)); return sb.toString(); } catch (Exception e) { return ""; diff --git a/app/src/main/java/com/fongmi/android/tv/utils/Json.java b/app/src/main/java/com/fongmi/android/tv/utils/Json.java index 4b6766d8f..6cd811f7e 100644 --- a/app/src/main/java/com/fongmi/android/tv/utils/Json.java +++ b/app/src/main/java/com/fongmi/android/tv/utils/Json.java @@ -4,12 +4,23 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; +import org.json.JSONObject; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; public class Json { + public static boolean valid(String text) { + try { + new JSONObject(text); + return true; + } catch (Exception e) { + return false; + } + } + public static String safeString(JsonObject obj, String key, String value) { if (obj.has(key)) return obj.getAsJsonPrimitive(key).getAsString().trim(); else return value; diff --git a/app/src/main/java/com/fongmi/android/tv/utils/Utils.java b/app/src/main/java/com/fongmi/android/tv/utils/Utils.java index b25eaa955..4d5a5ed21 100644 --- a/app/src/main/java/com/fongmi/android/tv/utils/Utils.java +++ b/app/src/main/java/com/fongmi/android/tv/utils/Utils.java @@ -86,9 +86,9 @@ public class Utils { public static String getMD5(String src) { try { if (TextUtils.isEmpty(src)) return ""; - MessageDigest md = MessageDigest.getInstance("MD5"); - byte[] messageDigest = md.digest(src.getBytes()); - BigInteger no = new BigInteger(1, messageDigest); + MessageDigest digest = MessageDigest.getInstance("MD5"); + byte[] bytes = digest.digest(src.getBytes()); + BigInteger no = new BigInteger(1, bytes); StringBuilder sb = new StringBuilder(no.toString(16)); while (sb.length() < 32) sb.insert(0, "0"); return sb.toString().toLowerCase(); From 72a8a23db45999c60c1205e61fd68c0f5a28aef0 Mon Sep 17 00:00:00 2001 From: FongMi Date: Tue, 11 Oct 2022 20:09:52 +0800 Subject: [PATCH 3/5] Fix decode to hex --- .../com/fongmi/android/tv/api/ApiConfig.java | 4 +- .../com/fongmi/android/tv/api/Decoder.java | 6 +- .../java/com/fongmi/android/tv/utils/AES.java | 77 ------------------- .../com/fongmi/android/tv/utils/Updater.java | 2 +- 4 files changed, 6 insertions(+), 83 deletions(-) delete mode 100644 app/src/main/java/com/fongmi/android/tv/utils/AES.java diff --git a/app/src/main/java/com/fongmi/android/tv/api/ApiConfig.java b/app/src/main/java/com/fongmi/android/tv/api/ApiConfig.java index b6a8c663e..3488fa4b8 100644 --- a/app/src/main/java/com/fongmi/android/tv/api/ApiConfig.java +++ b/app/src/main/java/com/fongmi/android/tv/api/ApiConfig.java @@ -84,7 +84,7 @@ public class ApiConfig { public void loadConfig(boolean cache, Callback callback) { new Thread(() -> { if (cache) loadCache(Prefers.getUrl(), callback); - else loadJson(Prefers.getUrl(), callback); + else loadConfig(Prefers.getUrl(), callback); }).start(); } @@ -94,7 +94,7 @@ public class ApiConfig { else handler.post(() -> callback.error(R.string.error_config_get)); } - private void loadJson(String url, Callback callback) { + private void loadConfig(String url, Callback callback) { try { parseConfig(new Gson().fromJson(Decoder.getJson(url), JsonObject.class), callback); } catch (Exception e) { diff --git a/app/src/main/java/com/fongmi/android/tv/api/Decoder.java b/app/src/main/java/com/fongmi/android/tv/api/Decoder.java index 26f74a973..f730d5e40 100644 --- a/app/src/main/java/com/fongmi/android/tv/api/Decoder.java +++ b/app/src/main/java/com/fongmi/android/tv/api/Decoder.java @@ -64,9 +64,9 @@ public class Decoder { } private static byte[] decodeHex(String s) { - int len = s.length(); - byte[] data = new byte[len / 2]; - for (int i = 0; i < len; i += 2) data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16)); + int len = s.length() / 2; + byte[] data = new byte[len]; + for (int i = 0; i < len; i++) data[i] = Integer.valueOf(s.substring(i * 2, i * 2 + 2), 16).byteValue(); return data; } } diff --git a/app/src/main/java/com/fongmi/android/tv/utils/AES.java b/app/src/main/java/com/fongmi/android/tv/utils/AES.java deleted file mode 100644 index a3630e2a1..000000000 --- a/app/src/main/java/com/fongmi/android/tv/utils/AES.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.fongmi.android.tv.utils; - -import com.github.catvod.crawler.SpiderDebug; - -import org.json.JSONObject; - -import java.security.spec.AlgorithmParameterSpec; - -import javax.crypto.Cipher; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.SecretKeySpec; - -public class AES { - - public static String rightPading(String key, String replace, int Length) { - String strReturn = ""; - String strtemp = ""; - int curLength = key.trim().length(); - if (key != null && curLength > Length) { - strReturn = key.trim().substring(0, Length); - } else if (key != null && curLength == Length) { - strReturn = key.trim(); - } else { - for (int i = 0; i < (Length - curLength); i++) { - strtemp = strtemp + replace; - } - strReturn = key.trim() + strtemp; - } - return strReturn; - } - - public static String ECB(String data, String key) { - try { - key = rightPading(key, "0", 16); - byte[] data2 = toBytes(data); - SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "AES"); - Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding"); - cipher.init(Cipher.DECRYPT_MODE, keySpec); - return new String(cipher.doFinal(data2)); - } catch (Exception exception) { - SpiderDebug.log(exception); - } - return null; - } - - public static String CBC(String src, String KEY, String IV) { - try { - Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); - SecretKeySpec keySpec = new SecretKeySpec(KEY.getBytes(), "AES"); - AlgorithmParameterSpec paramSpec = new IvParameterSpec(IV.getBytes()); - cipher.init(Cipher.DECRYPT_MODE, keySpec, paramSpec); - return new String(cipher.doFinal(toBytes(src))); - } catch (Exception exception) { - SpiderDebug.log(exception); - } - return null; - } - - public static byte[] toBytes(String src) { - int l = src.length() / 2; - byte[] ret = new byte[l]; - for (int i = 0; i < l; i++) { - ret[i] = Integer.valueOf(src.substring(i * 2, i * 2 + 2), 16).byteValue(); - } - return ret; - } - - public static boolean isJson(String content) { - try { - new JSONObject(content); - return true; - } catch (Exception e) { - return false; - } - } - -} diff --git a/app/src/main/java/com/fongmi/android/tv/utils/Updater.java b/app/src/main/java/com/fongmi/android/tv/utils/Updater.java index 24a995a0a..8aa506aa1 100644 --- a/app/src/main/java/com/fongmi/android/tv/utils/Updater.java +++ b/app/src/main/java/com/fongmi/android/tv/utils/Updater.java @@ -22,7 +22,7 @@ import java.util.concurrent.Executors; public class Updater implements View.OnClickListener { - private static final String URL = "https://github.com/FongMi/TV/raw/main/release/leanback.json"; + private static final String URL = "https://raw.githubusercontent.com/FongMi/TV/release/release/leanback.json"; private static final String PROXY = "https://ghproxy.com/"; private final ExecutorService executor; From 31d4cee853e11ab8add4bd6e942d3fec63350665 Mon Sep 17 00:00:00 2001 From: FongMi Date: Tue, 11 Oct 2022 21:53:11 +0800 Subject: [PATCH 4/5] Fix bug --- app/src/main/java/com/fongmi/android/tv/api/Decoder.java | 8 +++----- .../main/java/com/fongmi/android/tv/utils/FileUtil.java | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/fongmi/android/tv/api/Decoder.java b/app/src/main/java/com/fongmi/android/tv/api/Decoder.java index f730d5e40..e4bfe2a68 100644 --- a/app/src/main/java/com/fongmi/android/tv/api/Decoder.java +++ b/app/src/main/java/com/fongmi/android/tv/api/Decoder.java @@ -5,6 +5,7 @@ import android.util.Base64; import com.fongmi.android.tv.net.OKHttp; import com.fongmi.android.tv.utils.FileUtil; import com.fongmi.android.tv.utils.Json; +import com.google.common.io.BaseEncoding; import java.nio.charset.StandardCharsets; @@ -63,10 +64,7 @@ public class Decoder { return (key + "0000000000000000".substring(key.length())).getBytes(StandardCharsets.UTF_8); } - private static byte[] decodeHex(String s) { - int len = s.length() / 2; - byte[] data = new byte[len]; - for (int i = 0; i < len; i++) data[i] = Integer.valueOf(s.substring(i * 2, i * 2 + 2), 16).byteValue(); - return data; + public static byte[] decodeHex(String hexString) { + return BaseEncoding.base16().decode(hexString.toUpperCase()); } } diff --git a/app/src/main/java/com/fongmi/android/tv/utils/FileUtil.java b/app/src/main/java/com/fongmi/android/tv/utils/FileUtil.java index 22050b87b..b5e59eea6 100644 --- a/app/src/main/java/com/fongmi/android/tv/utils/FileUtil.java +++ b/app/src/main/java/com/fongmi/android/tv/utils/FileUtil.java @@ -70,7 +70,7 @@ public class FileUtil { BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(getLocal(path)))); StringBuilder sb = new StringBuilder(); String text; - while ((text = br.readLine()) != null) sb.append(text).append("\n"); + while ((text = br.readLine()) != null) sb.append(text); br.close(); return sb.toString(); } catch (Exception e) { From 221a8d82baa4f1ae51ab366cadb9a75af284bb40 Mon Sep 17 00:00:00 2001 From: FongMi Date: Tue, 11 Oct 2022 22:35:32 +0800 Subject: [PATCH 5/5] Fix decode bug --- .../com/fongmi/android/tv/api/Decoder.java | 25 ++++++++++++++++--- .../com/fongmi/android/tv/api/JarLoader.java | 2 +- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/fongmi/android/tv/api/Decoder.java b/app/src/main/java/com/fongmi/android/tv/api/Decoder.java index e4bfe2a68..b62d7cc8d 100644 --- a/app/src/main/java/com/fongmi/android/tv/api/Decoder.java +++ b/app/src/main/java/com/fongmi/android/tv/api/Decoder.java @@ -20,10 +20,27 @@ public class Decoder { url = url.contains(";") ? url.split(";")[0] : url; String data = getData(url); if (Json.valid(data)) return data; - if (key.length() > 0) return ecb(data, key); if (data.contains("**")) data = base64(data); if (data.startsWith("2423")) data = cbc(data); - return data.replace("###", ""); + if (key.length() > 0) data = ecb(data, key); + return data; + } + + public static String getExt(String ext) { + try { + return base64(OKHttp.newCall(ext.substring(4)).execute().body().string()); + } catch (Exception ignored) { + return ""; + } + } + + public static void getSpider(String jar) { + try { + String data = OKHttp.newCall(jar.substring(4)).execute().body().string(); + data = data.substring(data.indexOf("**") + 2); + FileUtil.write(FileUtil.getJar(jar), Base64.decode(data, Base64.DEFAULT)); + } catch (Exception ignored) { + } } private static String getData(String url) throws Exception { @@ -64,7 +81,7 @@ public class Decoder { return (key + "0000000000000000".substring(key.length())).getBytes(StandardCharsets.UTF_8); } - public static byte[] decodeHex(String hexString) { - return BaseEncoding.base16().decode(hexString.toUpperCase()); + public static byte[] decodeHex(String s) { + return BaseEncoding.base16().decode(s.toUpperCase()); } } diff --git a/app/src/main/java/com/fongmi/android/tv/api/JarLoader.java b/app/src/main/java/com/fongmi/android/tv/api/JarLoader.java index 85b1fae76..6ea7f90a7 100644 --- a/app/src/main/java/com/fongmi/android/tv/api/JarLoader.java +++ b/app/src/main/java/com/fongmi/android/tv/api/JarLoader.java @@ -65,7 +65,7 @@ public class JarLoader { public void parseJar(String key, String jar) { String[] texts = jar.split(";md5;"); - String md5 = jar.startsWith("http") && texts.length > 1 ? texts[1].trim() : ""; + String md5 = !jar.startsWith("file") && texts.length > 1 ? texts[1].trim() : ""; jar = texts[0]; if (md5.length() > 0 && FileUtil.equals(jar, md5)) { load(key, FileUtil.getJar(jar));