using Newtonsoft.Json; using System.Collections; using System; using System.Collections.Generic; using System.IO; using UnityEngine; using UnityEngine.UI; using System.Security.Cryptography; using Sirenix.Utilities; using System.Security.Policy; using System.Text; public class SecurityCheck : MonoBehaviour { private string hashFileName = "sec_code.json";// 用于存储文件路径和对应哈希值的字典 private Dictionary AS_fileHashes = new Dictionary();//文件中Hash private Dictionary fileHashes = new Dictionary();//当前文件Hash private string appFolderPath = Application.streamingAssetsPath + "\\..\\..\\"; public List skip_files = new List();//读取跳过的文件 [HideInInspector] public int total = 0;//总文件数量 [HideInInspector] public int read = 0; [HideInInspector] public bool check_finish = false; [HideInInspector] public bool result = false; public static SecurityCheck instance; List files = new List(); [HideInInspector] public string debugStr = ""; // 获取文件哈希值的方法 private string GetHash(string path) { using (var hash = SHA256.Create()) using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read)) { byte[] hashBytes = hash.ComputeHash(stream); return BitConverter.ToString(hashBytes).Replace("-", "").ToLower(); } } IEnumerator CalculateHashes(List files) { if (AS_fileHashes == null || AS_fileHashes.Count == 0)//没有校验文件 { Debug.Log("缺少校验文件"); result = false; check_finish = true; yield break; } if (files.Count != AS_fileHashes.Count) { Debug.Log("文件数量不对"); #if UNITY_EDITOR foreach (var item in files) { bool find = false; string f_name = Path.GetFileName(item).ToLower(); foreach (var item2 in AS_fileHashes) { //string f_name2 = Path.GetFileName(y.Key); //Debug.Log("===>" + f_name); if (item2.Key.Contains(f_name)) { find = true; break; } } if (!find) { Debug.Log("缺少文件:" + f_name); } } #endif result = false; check_finish = true; yield break; } check_finish = false; total = files.Count; read = 0; foreach (string filePath in files) { try { string absolutePath = Path.GetFullPath(filePath); string hash = GetHash(absolutePath); string relativePath = PathUtils.GetRelativeToStreamingAssets(absolutePath, true); debugStr = relativePath; if (!AS_fileHashes.ContainsKey(relativePath) || !hash.Equals(AS_fileHashes[relativePath])) { if (!AS_fileHashes.ContainsKey(relativePath)) Debug.Log("缺少文件:" + absolutePath + "=>" + relativePath); else Debug.Log("值不对:" + relativePath + "\n" + hash + "\n" + AS_fileHashes[relativePath]); //Debug.LogError($"MD5错误"); result = false; check_finish = true; yield break; } //} //fileHashes[filePath] = hash; } catch (Exception ex) { Debug.LogError($"Error calculating hash for file {filePath}: {ex.Message}"); result = false; check_finish = true; yield break; } read++; yield return null; } result = true; check_finish = true; } private void Awake() { instance = this; check_finish = false; fileHashes.Clear(); AS_fileHashes.Clear(); files.Clear(); AS_fileHashes = LoadHashesFromJson(Application.streamingAssetsPath + "\\" + hashFileName); #if UNITY_EDITOR appFolderPath = "E:\\HQB\\文件打包\\0402\\10002\\"; #endif try { string[] allFiles = Directory.GetFiles(appFolderPath, "*", SearchOption.AllDirectories); allFiles.ForEach(x => { bool skip = false; foreach (var item in skip_files) { if (x.Contains(item.Trim())) { skip = true; break; } } if (!skip) files.Add(x); }); total = files.Count; } catch (Exception ex) { Debug.LogError("校验文件读取故障:" + ex.Message); } StartCoroutine(CalculateHashes(files)); } public string DecodeFromBase64(string encoded) { byte[] encodedBytes = Convert.FromBase64String(encoded); return Encoding.UTF8.GetString(encodedBytes); } private Dictionary LoadHashesFromJson(string filePath) { if (!File.Exists(filePath)) { Debug.LogError($"File not found at path: {filePath}"); return null; } try { string json64 = File.ReadAllText(filePath); string json = DecodeFromBase64(json64); Dictionary hashes = JsonConvert.DeserializeObject>(json); Debug.Log($"Hashes loaded from {filePath}"); return hashes; } catch (Exception ex) { Debug.LogError($"Failed to load hashes from {filePath}: {ex.Message}"); return null; } } }