103 lines
3.9 KiB
C#
103 lines
3.9 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using LoveLegend;
|
|
|
|
namespace LoveLegend
|
|
{
|
|
|
|
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;
|
|
}
|
|
}
|
|
} |