using System; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; using RedHotRoast; namespace RedHotRoast { public class Rescrypt { // 魔法字节标记 private static readonly byte[] Magic = Encoding.UTF8.GetBytes("SGENCRY"); // 解密文件:从 src 读出,解密后写到 dst public static void DecryptFile(string src, string dst) { var key = ConfigSystem.GetCommonConf().ResVersion; var data = File.ReadAllBytes(src); // 检查魔法字节 if (data.Length < Magic.Length || !data.Take(Magic.Length).SequenceEqual(Magic)) throw new InvalidDataException("文件未加密或格式错误"); // 去掉魔法字节 var raw = data.Skip(Magic.Length).ToArray(); // 使用 MD5.Create() 计算 MD5 byte[] rawHash; using (var md5 = MD5.Create()) { rawHash = md5.ComputeHash(Encoding.UTF8.GetBytes(key)); } // 转成 32 字节十六进制 ASCII,与 Go 端 hex.EncodeToString 对应 var keyBytes = Encoding.ASCII.GetBytes(BitConverter.ToString(rawHash).Replace("-", "").ToLower()); // 解密 var dec = KeyReverseDecryptData(raw, keyBytes); // 写出解密后的文件 File.WriteAllBytes(dst, dec); // 删除临时源文件(加密的) File.Delete(src); } public static byte[] DecryptFileToBytes(string src) { var data = File.ReadAllBytes(src); var key = ConfigSystem.GetCommonConf().ResVersion; // 检查魔法字节 if (data.Length < Magic.Length || !data.Take(Magic.Length).SequenceEqual(Magic)) throw new InvalidDataException("文件未加密或格式错误"); // 去掉魔法字节 var raw = data.Skip(Magic.Length).ToArray(); // 使用 MD5.Create() 计算 MD5 byte[] rawHash; using (var md5 = MD5.Create()) { rawHash = md5.ComputeHash(Encoding.UTF8.GetBytes(key)); } // 转成 32 字节十六进制 ASCII,与 Go 端 hex.EncodeToString 对应 var keyBytes = Encoding.ASCII.GetBytes(BitConverter.ToString(rawHash).Replace("-", "").ToLower()); // 解密并返回 return KeyReverseDecryptData(raw, keyBytes); } public static byte[] DecryptVideoToBytes(string src) { var key = ConfigSystem.GetCommonConf().ResVersion; var data = File.ReadAllBytes(src); if (data.Length < Magic.Length || !data.Take(Magic.Length).SequenceEqual(Magic)) throw new InvalidDataException("视频未加密或格式错误"); var raw = data.Skip(Magic.Length).ToArray(); // 使用 MD5.Create() 计算 MD5 byte[] rawHash; using (var md5 = MD5.Create()) { rawHash = md5.ComputeHash(Encoding.UTF8.GetBytes(key)); } // 转成 32 字节十六进制 ASCII,与 Go 端 hex.EncodeToString 对应 var keyBytes = Encoding.ASCII.GetBytes(BitConverter.ToString(rawHash).Replace("-", "").ToLower()); return KeyReverseDecryptData(raw, keyBytes); } // 基础解密:XOR + 反序 private static byte[] KeyReverseDecryptData(byte[] data, byte[] key) { var keyLen = key.Length; // XOR for (var i = 0; i < data.Length; i++) data[i] ^= key[i % keyLen]; // 反序 for (int i = 0, j = data.Length - 1; i < j; i++, j--) (data[i], data[j]) = (data[j], data[i]); return data; } } }