using Fiddler; using FiddlerDecryption.Utils; using Flurl.Http; using Newtonsoft.Json.Linq; using System; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; namespace Util { class DecodeUtil { static Uri GetAPIUri(string path) { Setting setting = Setting.Instance; Uri uri = new Uri(setting.ApiHost); string scheme = uri.Scheme.ToLower(); if (scheme != "http" && scheme != "https") { setting.ApiHost = Setting.DEFAULT_API_HOST; uri = new Uri(setting.ApiHost); } UriBuilder builder = new UriBuilder(uri); builder.Path += path; return builder.Uri; } /// /// 清除返回 JObject 中 cachedSize 和 serializedSize 字段 /// /// /// public static JToken ClearSizeInfo(JToken j) { if (j == null) return null; if (j is JArray ja) { for (int i = 0; i < ja.Count; i++) { ja[i] = ClearSizeInfo(ja[i]); } return ja; } if (j is JObject jo) { jo.Remove("cachedSize"); jo.Remove("serializedSize"); foreach (var p in jo) { string key = p.Key; JToken val = p.Value; jo[key] = ClearSizeInfo(val); } return jo; } return j; } public static async Task DoDecryptionNew(HTTPRequestHeaders headers, byte[] mBody) { if (NeedToDecrypt(headers)) { var url = "http://localhost:7790/api/v1/proto/request/decode"; try { string r = await url.PostJsonAsync(new { protocolId = Convert.ToInt32(headers["X-Protocol-Id"]), protocolBody = Convert.ToBase64String(mBody) }).Result.GetStringAsync(); if (r != null) { JObject jo = JObject.Parse(r); return ClearSizeInfo(jo) as JObject; } else { return null; } } catch (Exception ex) { return new JObject() { new JProperty("ok", false), new JProperty("resultCode", 502), new JProperty("message", ex.InnerException?.Message ?? ex.Message) }; } } return null; } public static async Task DoDecryption(HTTPRequestHeaders headers, byte[] mBody) { // 判断是否是对应内容 string showBody = ""; if (NeedToDecrypt(headers)) { var url = "http://localhost:7790/api/v1/proto/request/decode"; try { string r = await url.PostJsonAsync(new { protocolId = Convert.ToInt32(headers["X-Protocol-Id"]), protocolBody = Convert.ToBase64String(mBody) }).Result.GetStringAsync(); if (r != null) { JObject jo = JObject.Parse(r); if (jo["ok"].Value()) { JObject result = jo["data"].Value(); result = ClearSizeInfo(result) as JObject; jo["data"] = result; } showBody = jo.ToString(); } else { return null; } } catch (Exception ex) { showBody = ex.Message; } } return Encoding.UTF8.GetBytes(showBody); } public static async Task DoDecryption(HTTPResponseHeaders headers, byte[] mBody) { // 判断是否是对应内容 string showBody = ""; if (NeedToDecrypt(headers)) { var url = "http://localhost:7790/api/v1/proto/response/decode"; try { int? protocolId = headers["X-Protocol-Id"] == null ? (int?)null : Convert.ToInt32(headers["X-Protocol-Id"]); string r = await url.PostJsonAsync(new { protocolId, protocolBody = Convert.ToBase64String(mBody) }).Result.GetStringAsync(); if (r != null) { JObject jo = JObject.Parse(r); if (jo["ok"].Value()) { JObject result = jo["data"].Value(); result = ClearSizeInfo(result) as JObject; jo["data"] = result; } showBody = jo.ToString(); } else { return null; } } catch (Exception ex) { showBody = ex.Message; } } return Encoding.UTF8.GetBytes(showBody); } /// /// 请求是否需要做益盟解密 /// /// 请求的 Headers /// public static bool NeedToDecrypt(HTTPRequestHeaders headers) { if (headers.Exists("Host") && headers.Exists("Content-Type") && headers.Exists("X-Protocol-Id")) { var host = headers["Host"]; var contentType = headers["Content-Type"]; var protocolId = headers["X-Protocol-Id"]; return Regex.IsMatch(protocolId, "^\\d+$") && host.ToLower().EndsWith(".emoney.cn") && contentType.ToLower().Contains("application/x-protobuf-v3"); } return false; } /// /// 响应是否需要做益盟解密 /// /// 返回的 Headers /// public static bool NeedToDecrypt(HTTPResponseHeaders headers) { if (headers.Exists("Content-Type") && headers.Exists("X-Protocol-Id")) { var contentType = headers["Content-Type"]; var protocolId = headers["X-Protocol-Id"]; return Regex.IsMatch(protocolId, "^\\d+$") && contentType.ToLower().Contains("application/x-protobuf-v3"); } return false; } } }