pull/123/head
FongMi 4 years ago
parent b5f914e010
commit 8aad7c86bb
  1. 106
      app/src/main/java/com/fongmi/android/tv/api/ApiConfig.java
  2. 72
      app/src/main/java/com/fongmi/android/tv/api/Decoder.java
  3. 3
      app/src/main/java/com/fongmi/android/tv/utils/FileUtil.java
  4. 11
      app/src/main/java/com/fongmi/android/tv/utils/Json.java
  5. 6
      app/src/main/java/com/fongmi/android/tv/utils/Utils.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);

@ -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;
}
}

@ -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 "";

@ -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;

@ -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();

Loading…
Cancel
Save