This commit is contained in:
1415ddfer 2024-03-09 18:29:16 +08:00
parent dc4233d645
commit d09249272c
19 changed files with 472 additions and 190 deletions

View File

@ -10,7 +10,7 @@
<DockPanel>
<TextBlock Text="关&#13;于" Margin="20" FontSize="50" Foreground="OrangeRed"/>
<StackPanel>
<TextBlock x:Name="info" Text=" 铃依登陆器&#13;&#13;The best luancher&#13; Power by DDF" Margin="30,150,30,30" HorizontalAlignment="Center" Foreground="#2e4e7e" FontSize="16"/>
<TextBlock x:Name="info" Text=" 灵依游戏大厅&#13;&#13;The best luancher&#13; Power by DDF" Margin="30,150,30,30" HorizontalAlignment="Center" Foreground="#2e4e7e" FontSize="16"/>
<TextBlock Text="Contact me" HorizontalAlignment="Center" Foreground="#FF81EB78"/>
<TextBlock HorizontalAlignment="Center">
<Hyperlink NavigateUri="https://github.com/1415ddfer/ZeroHelper" Click="Hyperlink_Click">

View File

@ -1,7 +1,6 @@
<Application x:Class="Zerolauncher.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Zerolauncher"
StartupUri="MainWindow.xaml">
<Application.Resources>

View File

@ -11,11 +11,26 @@ namespace Zerolauncher
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
_ = UpDateManager.TakeQMessage();
var a = CloundMananger.TakeQMessage();
a.Wait();
UpDateManager.DoCheckUpdate();
if (DownloadTask.state)
{
}else
{
DataStream.Load();
_ = WebApiManager.StartListener();
AccountManager.initLoadData();
}
}
protected override void OnExit(ExitEventArgs e)
{
base.OnExit(e);
WebApiManager.StopListener();
}
}
}

View File

@ -3,33 +3,57 @@ using System.Text;
namespace Zerolauncher.Defender
{
class EngineCacheSha
class CacheSha
{
const string key = "mysecretkey";
static string? sha;
static string? sha_engine;
static string? sha_main;
public static int errorCode = 0;
public static void Put(string eSha)
public static void PutE(string eSha)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < eSha.Length; i++)
{
sb.Append((char)(eSha[i] ^ key[i % key.Length]));
}
sha = sb.ToString();
sha_engine = sb.ToString();
}
public static string? Get()
public static string? GetE()
{
if (sha == null) { return null; }
if (sha_engine == null) { return null; }
var sb = new StringBuilder();
for (int i = 0; i < sha.Length; i++)
for (int i = 0; i < sha_engine.Length; i++)
{
sb.Append((char)(sha[i] ^ key[i % key.Length]));
sb.Append((char)(sha_engine[i] ^ key[i % key.Length]));
}
return sb.ToString();
}
public static void PutM(string eSha)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < eSha.Length; i++)
{
sb.Append((char)(eSha[i] ^ key[i % key.Length]));
}
sha_main = sb.ToString();
}
public static string? GetM()
{
if (sha_main == null) { return null; }
var sb = new StringBuilder();
for (int i = 0; i < sha_main.Length; i++)
{
sb.Append((char)(sha_main[i] ^ key[i % key.Length]));
}
return sb.ToString();
}
}
}

View File

@ -145,7 +145,6 @@ namespace Zerolauncher
private void Button_Click_3(object sender, RoutedEventArgs e)
{
WebApiManager.StopListener();
Close();
}

82
Manager/CloundMananger.cs Normal file
View File

@ -0,0 +1,82 @@
using System.Net.Http;
using System.Net;
using Zerolauncher.Defender;
using Zerolauncher.util;
namespace Zerolauncher.Manager
{
class StaticUrl
{
public const string QMessageMain = "https://sharechain.qq.com/";
public const string MasterMessage = "54aeb77c47b967d22c2c1396d00d91f0";
public const string SummerMessage = "037846c482eddc948612b0d0f8ed98d5";
public const string LoveMessage = "";
}
class UpDateData
{
public static bool state = false;
public static string version = "";
public static string tis = "";
public static string mini_packet_url = "";
public static string full_packet_url = "";
}
class CloundMananger
{
public static async Task TakeQMessage()
{
var client = new HttpClient();
client.DefaultRequestVersion = HttpVersion.Version20;
client.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrLower;
client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (iPad; U; CPU OS 6_0 like Mac OS X; zh-CN; iPad2)");
HttpResponseMessage response;
try
{
client.Timeout = TimeSpan.FromMinutes(3);
response = await client.GetAsync($"{StaticUrl.QMessageMain}{StaticUrl.MasterMessage}");
}
catch (Exception _ex)
{
CacheSha.errorCode = 1;
return;
}
var responseString = await response.Content.ReadAsStringAsync();
if(!FormatMessage(responseString))
{
CacheSha.errorCode = 2;
}
}
static bool FormatMessage(string message)
{
message = message.Split("<div class=\"note-content\">")[1].Split("</article>")[0].Replace("</div>", "").Replace("\n", "").Replace("\t", "").Replace("\r", "").Replace("'", "");
var arr = message.Split("<div>");
if (arr.Length >= 7 && FormatSha(arr[6], false) && FormatSha(arr[5], true))
{
UpDateData.version = arr[1];
UpDateData.tis = arr[2];
UpDateData.mini_packet_url = arr[3];
UpDateData.full_packet_url = arr[4];
UpDateData.state = true;
return true;
}
return false;
}
static bool FormatSha(string sha0, bool e)
{
if (sha0.Length < 90) return false;
int count;
var sha = SpaceEncoder.Decode(sha0[..86], out count);
if (sha == null)
{
//Console.WriteLine($"faile: {count}");
return false;
}
if (e) CacheSha.PutE(sha);
else CacheSha.PutM(sha);
return true;
}
}
}

View File

@ -20,7 +20,7 @@ namespace Zerolauncher.Manager
else
{
dataStream = JsonConvert.DeserializeObject<Data>(
"{\"teamIndex\":0,\"Groups\":[{\"Name\":\"队伍1\", \"Accounts\": [{\"providerId\":0,\"userName\":\"test\",\"userPWD\":\"test\",\"nickName\":\"测试账号\",\"serverId\":\"1\"}]}]}");
"{\"teamIndex\":0,\"Groups\":[{\"Name\":\"队伍1\", \"Accounts\": [{\"providerId\":0,\"userName\":\"test\",\"userPWD\":\"test\",\"nickName\":\"测试账号\",\"serverId\":\"1\"}]}], \"engine_cache_ver\": 0}");
}
}
@ -85,5 +85,6 @@ namespace Zerolauncher.Manager
{
public int teamIndex;
public List<Group> Groups;
public int engine_cache_ver;
}
}

View File

@ -19,10 +19,11 @@ namespace Zerolauncher.Manager
public static bool CreateGame(Account account)
{
var key = AccToKey(account);
if (mGame.ContainsKey(key)) { return false; }
if (EngineCacheSha.errorCode != 0) {
switch (EngineCacheSha.errorCode)
if (CacheSha.errorCode != 0) {
switch (CacheSha.errorCode)
{
case 1:
MessageBox.Show("发生网络错误==EMS。\n 请检查网络", "错误", MessageBoxButton.OKCancel, MessageBoxImage.Error);
@ -118,23 +119,36 @@ namespace Zerolauncher.Manager
public int mHandle;
public Account account;
public Account? account;
string gameMode;
public SingleGame(Account acc)
public SingleGame(Account? acc, string mod = StaticHandleA.GameMode)
{
restartUrl = null;
this.account = acc;
account = acc;
gameMode = mod;
mHandle = 0;
process = EngineShell.CheckEngineSafe();
process = EngineShell.CheckEngineSafe(gameMode);
if (gameMode != StaticHandleA.UpdateMode)
{
process.OutputDataReceived += Handle;
process.Exited += Process_Exited;
}
process.Start();
if (gameMode != StaticHandleA.UpdateMode)
{
process.BeginOutputReadLine(); // 开始异步读取
if (gameMode == StaticHandleA.Version)
{
process.WaitForExit();
}
}
}
private void CreateProcess()
{
process = EngineShell.CheckEngineSafe();
process = EngineShell.CheckEngineSafe(gameMode);
process.OutputDataReceived += Handle;
process.Exited += Process_Exited;
process.Start();
@ -143,12 +157,13 @@ namespace Zerolauncher.Manager
private void Process_Exited(object? sender, EventArgs e)
{
Trace.WriteLine(
$"Exit time : {process.ExitTime}\n" +
$"Exit code : {process.ExitCode}\n" +
$"Elapsed time : {Math.Round((process.ExitTime - process.StartTime).TotalMilliseconds)}");
Trace.WriteLine($"进程已退出:{account.nickName}");
if ( restartUrl == null )
//Trace.WriteLine(
// $"Exit time : {process.ExitTime}\n" +
// $"Exit code : {process.ExitCode}\n" +
// $"Elapsed time : {Math.Round((process.ExitTime - process.StartTime).TotalMilliseconds)}");
//Trace.WriteLine($"进程已退出:{account.nickName}");
if (gameMode != StaticHandleA.GameMode) return;
if ( restartUrl == null)
{
EngineManager.OnGameExit(account);
return;
@ -165,7 +180,11 @@ namespace Zerolauncher.Manager
if(restartUrl == null)
{
Send($"{StaticHandleS.ShowWindow} {ServicesStaticInfo.ServicesName[account.providerId]}-{account.nickName}");
_ = LoginManager.DoLogin(this);
Task.Run(async delegate
{
if (lines[1] == "True") await Task.Delay(5000);
_ =LoginManager.DoLogin(this);
});
}
else
{
@ -181,6 +200,9 @@ namespace Zerolauncher.Manager
restartUrl = lines[1];
Send(StaticHandleS.CloseGame);
break;
case StaticHandleC.Version:
mHandle = int.Parse(lines[1]);
break;
}
}
@ -204,31 +226,33 @@ namespace Zerolauncher.Manager
{
static bool is_check = false;
const string engine_file = @"ZeroEngine.exe";
public static Process CheckEngineSafe()
public static Process CheckEngineSafe(string mod)
{
if (!is_check && EngineManager.CheckEmpy())
{
string? now_bit;
using (SHA256 sha256 = SHA256.Create())
{
using (FileStream fileStream = File.OpenRead(engine_file))
{
byte[] hashBytes = sha256.ComputeHash(fileStream);
now_bit = BitConverter.ToString(hashBytes).Replace("-", string.Empty);
}
}
if (EngineCacheSha.Get() != now_bit)
{
throw new FileReadException("无法读取文件内容");
}
}
is_check = true;
bool is_first_luancher = EngineManager.CheckEmpy();
//if (!is_check && is_first_luancher)
//{
// string? now_bit;
// using (SHA256 sha256 = SHA256.Create())
// {
// using (FileStream fileStream = File.OpenRead(engine_file))
// {
// byte[] hashBytes = sha256.ComputeHash(fileStream);
// now_bit = BitConverter.ToString(hashBytes).Replace("-", string.Empty);
// }
// }
// if (EngineCacheSha.Get() != now_bit)
// {
// throw new FileReadException("无法读取文件内容");
// }
// is_check = true;
//}
var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = engine_file,
Arguments = StaticHandleA.GameMode,
Arguments = $"{mod} {is_first_luancher}",
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardInput = true,

View File

@ -57,7 +57,7 @@ namespace Zerolauncher.Manager
{
var client = new HttpClient();
string? need_web = null;
client.Timeout = TimeSpan.FromSeconds(10);
client.Timeout = TimeSpan.FromSeconds(3);
switch (game.account.providerId)
{
case 0:
@ -122,7 +122,16 @@ namespace Zerolauncher.Manager
break;
}
responseString = responseString.Split("name=\"game_box\"")[1].Split("src=\"")[1].Split("\"")[0];
try
{
response = await client.PostAsync(responseString, null);
}
catch (Exception ex)
{
game.Send($"{StaticHandleS.HintText} 网络发生错误,类型:{ex.GetType().Name.Replace(" ", "_")},消息:{ex.Message.Replace(" ", "_")}");
need_web = $"http://web.4399.com/stat/togame.php?target=ddt&server_id=S{game.account.serverId}";
break;
}
responseString = await response.Content.ReadAsStringAsync();
responseString = "http://" + response.RequestMessage.RequestUri.ToString().Split("/")[2] + "/" + responseString.Split("movie\" value='")[1].Split("'")[0];
Trace.WriteLine(responseString);

View File

@ -1,73 +1,62 @@
using System.IO;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography;
using Zerolauncher.Defender;
namespace Zerolauncher.Manager
{
class DownloadTask
{
public static bool state = false;
public static string url = "";
}
class UpDateManager
{
public static bool isCheeking = false;
public static async Task TakeQMessage()
public static void DoCheckUpdate(bool checkMain=true, bool needEngine = false)
{
var client = new HttpClient();
client.DefaultRequestVersion = HttpVersion.Version20;
client.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrLower;
client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (iPad; U; CPU OS 6_0 like Mac OS X; zh-CN; iPad2)");
HttpResponseMessage response;
try
if (isCheeking) return;
isCheeking=true;
bool needMian= false;
if(checkMain)
{
client.Timeout = TimeSpan.FromMinutes(3);
response = await client.GetAsync("https://sharechain.qq.com/037846c482eddc948612b0d0f8ed98d5"); // 初夏
}catch (Exception _ex)
string filePath = Process.GetCurrentProcess().MainModule.FileName;
string? now_bit;
using (SHA256 sha256 = SHA256.Create())
{
EngineCacheSha.errorCode = 1;
return;
using (FileStream fileStream = File.OpenRead(filePath))
{
byte[] hashBytes = sha256.ComputeHash(fileStream);
now_bit = BitConverter.ToString(hashBytes).Replace("-", string.Empty);
}
var responseString = await response.Content.ReadAsStringAsync();
responseString = responseString.Split("<div class=\"note-content\">")[1].Split("</article>")[0].Replace("</div>", "").Replace("\n", "").Replace("\t", "").Replace("\r", "").Replace("'", "");
var arr = responseString.Split("<div>").Last();
if (arr.Length < 90)
{
EngineCacheSha.errorCode = 2;
return;
}
int count;
var sha = SpaceEncoder.Decode(arr[..86], out count);
if (sha == null)
{
//Console.WriteLine($"faile: {count}");
EngineCacheSha.errorCode = 2;
return;
needMian = now_bit == CacheSha.GetM() && now_bit != null;
}
EngineCacheSha.Put(sha);
if(!needEngine)
{
string? now_bit;
using (SHA256 sha256 = SHA256.Create())
{
using (FileStream fileStream = File.OpenRead(@"ZeroEngine.exe"))
{
byte[] hashBytes = sha256.ComputeHash(fileStream);
now_bit = BitConverter.ToString(hashBytes).Replace("-", string.Empty);
}
}
needEngine = now_bit == CacheSha.GetE() && now_bit != null;
}
if(needEngine && needMian) { isCheeking = false; return; }
DownloadTask.state = true;
if(needEngine == needMian) DownloadTask.url = UpDateData.full_packet_url;
else DownloadTask.url = UpDateData.mini_packet_url;
isCheeking = false;
}
public async Task GetTask()
{
var client = new HttpClient();
client.DefaultRequestVersion = HttpVersion.Version20;
client.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrLower;
client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (iPad; U; CPU OS 6_0 like Mac OS X; zh-CN; iPad2)");
var response = await client.GetAsync("https://sharechain.qq.com/13111bbd6ffbffa3057878431bef103e");
var responseString = await response.Content.ReadAsStringAsync();
if (responseString.Contains("<div class=\"note-content\">"))
{
responseString = responseString.Split("<div class=\"note-content\">")[1].Split("</article>")[0].Replace("</div>", "").Replace("\n", "").Replace(" ", "").Replace("\t", "").Replace("\r", "").Replace("'", "");
Console.WriteLine(responseString.Replace("<div>", "\n"));
var arr = responseString.Split("<div>");
int main_version, engine_version, sa_version;
if (int.TryParse(arr[0], out main_version) && int.TryParse(arr[1], out engine_version))
{
}
}
// todo open faile update dialog
}
public static void DownLoad(string Url, string FileName)
public static void DownLoad(string Url, string FileName, bool has)
{
bool Value = false;
WebResponse response = null;

View File

@ -4,6 +4,5 @@
{
public static string[] ServicesName = ["4399大区", "7k7k大区", "第七大道"];
public static string[] ServicesShortName = ["43", "7k", "7d"];
}
}

View File

@ -17,11 +17,13 @@
public const string BrowserDone = "0b";
public const string StartGame = "0c";
public const string GameDone = "0d";
public const string Version = "0e";
}
class StaticHandleA
{
public const string GameMode = "0a";
public const string UpdateMode = "0b";
public const string Version = "0c";
}
}

View File

@ -37,6 +37,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Downloader" Version="3.0.6" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>

View File

@ -97,12 +97,14 @@ namespace Zerolauncher.dialog
baseDialog.Close();
}
}
}
class UpdateDialog
{
static BaseDialog? baseDialog;
static DownloadControl? editControl;
public static DownloadControl1? editControl;
public static bool ui_enale = false;
public static void CreateDailog(Window p)
{
@ -110,9 +112,11 @@ namespace Zerolauncher.dialog
{
return;
}
editControl = new DownloadControl();
editControl = new DownloadControl1();
baseDialog = new BaseDialog(editControl);
ui_enale = true;
baseDialog.ShowDialog();
ui_enale = false;
baseDialog = null;
editControl = null;
}

View File

@ -1,4 +1,4 @@
<UserControl x:Class="Zerolauncher.dialog.DownloadControl"
<UserControl x:Class="Zerolauncher.dialog.DownloadControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@ -7,8 +7,8 @@
d:DesignHeight="169" d:DesignWidth="290">
<StackPanel Margin="5">
<Image Source="/res/39376.jpg" Height="100"/>
<TextBlock Text="零蛋正在更新装备..." Foreground="PaleGoldenrod" HorizontalAlignment="Center" Margin="5"/>
<TextBlock Name="text1" Text="零蛋正在更新装备..." Foreground="PaleGoldenrod" HorizontalAlignment="Center" Margin="5"/>
<ProgressBar Name="pbDown" HorizontalAlignment="Center" Height="10" Width="200" Value="50"/>
<Label Name="label1" Content="0 kb/s--50%" Foreground="BurlyWood" HorizontalAlignment="Center"/>
<TextBlock Name="text2" Text="0 kb/s" Foreground="BurlyWood" HorizontalAlignment="Center"/>
</StackPanel>
</UserControl>

View File

@ -1,5 +1,5 @@
using System.IO;
using System.Net.Http;
using Downloader;
using System.ComponentModel;
using System.Windows.Controls;
namespace Zerolauncher.dialog
@ -7,97 +7,60 @@ namespace Zerolauncher.dialog
/// <summary>
/// DownloadControl.xaml 的交互逻辑
/// </summary>
public partial class DownloadControl : UserControl
public partial class DownloadControl1 : UserControl
{
const string cache_dir = "./.cache/auto.cache";
static bool is_strat = false;
public DownloadControl()
public DownloadControl1()
{
InitializeComponent();
if (!is_strat) text2.Text = "正在连接服务器";
}
private void OnError(Exception ex)
public static void DoDownload(string fileUrl)
{
// UnityEngine.Debug.Log("捕获异常 >>> " + ex);
var downloadOpt = new DownloadConfiguration()
{
ChunkCount = 8, // file parts to download, the default value is 1
ParallelDownload = true // download parts of the file as parallel or not. The default value is false
};
var downloader = new DownloadService(downloadOpt);
// Provide `FileName` and `TotalBytesToReceive` at the start of each download
downloader.DownloadStarted += OnDownloadStarted;
// Provide any information about download progress,
// like progress percentage of sum of chunks, total speed,
// average speed, total received bytes and received bytes array
// to live streaming.
downloader.DownloadProgressChanged += OnDownloadProgressChanged;
// Download completed event that can include errors or
// canceled or download completed successfully.
downloader.DownloadFileCompleted += OnDownloadFileCompleted;
}
public async Task Download(string fileUrl)
{
using (HttpClient client = new HttpClient())
{
// 获取文件大小
HttpResponseMessage responseHead = await client.SendAsync(new HttpRequestMessage(HttpMethod.Head, fileUrl));
long? contentLength = responseHead.Content.Headers.ContentLength;
Console.WriteLine($"文件大小:{contentLength} 字节");
// 计算块大小
int blockSize = 1024 * 1024; // 1MB
int blockCount = (int)Math.Ceiling((double)contentLength / blockSize);
// 创建SemaphoreSlim以限制同时进行的下载任务的数量
SemaphoreSlim semaphore = new SemaphoreSlim(4); // 最多允许4个并发下载任务
using (FileStream fileStream = new FileStream(cache_dir, FileMode.Create, FileAccess.Write, FileShare.None, blockSize, true))
{
// 创建任务列表
Task[] tasks = new Task[blockCount];
for (int i = 0; i < blockCount; i++)
{
int blockNumber = i;
tasks[i] = Task.Run(async () =>
{
await semaphore.WaitAsync(); // 等待获取许可
try
{
// 计算当前块的范围
var start = blockNumber * blockSize;
var end = (blockNumber == blockCount - 1) ? contentLength - 1 : start + blockSize - 1;
// 设置请求头,请求指定范围的数据
var request = new HttpRequestMessage { RequestUri = new Uri(fileUrl), Method = HttpMethod.Get };
request.Headers.Range = new System.Net.Http.Headers.RangeHeaderValue(start, end);
// 下载当前块
using (HttpResponseMessage response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
byte[] buffer = await response.Content.ReadAsByteArrayAsync();
await fileStream.WriteAsync(buffer, 0, buffer.Length);
}
// 显示下载进度
double percent = (double)(blockNumber + 1) / blockCount * 100;
Console.WriteLine($"已下载:{percent:F2}%");
}
finally
{
semaphore.Release(); // 释放许可
}
});
}
// 等待所有任务完成
await Task.WhenAll(tasks);
}
}
Console.WriteLine("下载完成!");
}
private void OnUpdate(long size, long count)
private static void OnDownloadFileCompleted(object? sender, AsyncCompletedEventArgs e)
{
}
private void OnDone(byte[] data)
private static void OnDownloadProgressChanged(object? sender, DownloadProgressChangedEventArgs e)
{
if (UpdateDialog.ui_enale)
{
UpdateDialog.editControl.pbDown.Value = e.ProgressPercentage;
UpdateDialog.editControl.text2.Text = $"{e.AverageBytesPerSecondSpeed}";
}
throw new NotImplementedException();
}
private void OnDestroy()
private static void OnDownloadStarted(object? sender, DownloadStartedEventArgs e)
{
is_strat = true;
if (UpdateDialog.ui_enale) UpdateDialog.editControl.text1.Text = "零蛋正在更新装备...";
}
}

9
util/Download.cs Normal file
View File

@ -0,0 +1,9 @@

namespace Zerolauncher.util
{
class Download
{
}
}

162
util/MyEncrypt.cs Normal file
View File

@ -0,0 +1,162 @@
using System.Security.Cryptography;
using System.IO;
namespace Zerolauncher.util
{
// MyEncrypt.SHA_Encrypt("test.txt", "test1.txt", "123456"); //文件加密
// MyEncrypt.SHA_Dencrypt("test1.txt", "test2.txt", "123456"); //文件解密
public class MyEncrypt
{
private const ulong FC_TAG = 0xFC010203040506CF;
private const int BUFFER_SIZE = 128 * 1024;
//检验两个Byte数组是否相同
private static bool CheckByteArrays(byte[] b1, byte[] b2)
{
if (b1.Length == b2.Length)
{
for (int i = 0; i < b1.Length; ++i)
{
if (b1[i] != b2[i])
return false;
}
return true;
}
return false;
}
/// <param name="password">密码</param>
/// <param name="salt"></param>
/// <returns>加密对象</returns>
private static SymmetricAlgorithm CreateRijndael(string password, byte[] salt)
{
PasswordDeriveBytes pdb = new PasswordDeriveBytes(password, salt, "SHA256", 1000);
SymmetricAlgorithm sma = Rijndael.Create();
sma.KeySize = 256;
sma.Key = pdb.GetBytes(32);
sma.Padding = PaddingMode.PKCS7;
return sma;
}
// 加密文件随机数生成
private static RandomNumberGenerator rand = new RNGCryptoServiceProvider();
// 生成指定长度的随机Byte数组
private static byte[] GenerateRandomBytes(int count)
{
byte[] bytes = new byte[count];
rand.GetBytes(bytes);
return bytes;
}
// 加密文件
public static void SHA_Encrypt(string inFile, string outFile, string password)
{
using (FileStream fin = File.OpenRead(inFile),
fout = File.OpenWrite(outFile))
{
long lSize = fin.Length; // 输入文件长度
int size = (int)lSize;
byte[] bytes = new byte[BUFFER_SIZE]; // 缓存
int read = -1; // 输入文件读取数量
int value = 0;
// 获取IV和salt
byte[] IV = GenerateRandomBytes(16);
byte[] salt = GenerateRandomBytes(16);
// 创建加密对象
SymmetricAlgorithm sma = CreateRijndael(password, salt);
sma.IV = IV;
// 在输出文件开始部分写入IV和salt
fout.Write(IV, 0, IV.Length);
fout.Write(salt, 0, salt.Length);
// 创建散列加密
HashAlgorithm hasher = SHA256.Create();
using (CryptoStream cout = new CryptoStream(fout, sma.CreateEncryptor(), CryptoStreamMode.Write),
chash = new CryptoStream(Stream.Null, hasher, CryptoStreamMode.Write))
{
BinaryWriter bw = new BinaryWriter(cout);
bw.Write(lSize);
bw.Write(FC_TAG);
// 读写字节块到加密流缓冲区
while ((read = fin.Read(bytes, 0, bytes.Length)) != 0)
{
cout.Write(bytes, 0, read);
chash.Write(bytes, 0, read);
value += read;
}
// 关闭加密流
chash.Flush();
chash.Close();
// 读取散列
byte[] hash = hasher.Hash;
// 输入文件写入散列
cout.Write(hash, 0, hash.Length);
// 关闭文件流
cout.Flush();
cout.Close();
}
}
}
// 解密文件
public static void SHA_Dencrypt(string inFile, string outFile, string password)
{
// 创建打开文件流
using (FileStream fin = File.OpenRead(inFile),
fout = File.OpenWrite(outFile))
{
int size = (int)fin.Length;
byte[] bytes = new byte[BUFFER_SIZE];
int read = -1;
int value = 0;
int outValue = 0;
byte[] IV = new byte[16];
fin.Read(IV, 0, 16);
byte[] salt = new byte[16];
fin.Read(salt, 0, 16);
SymmetricAlgorithm sma = CreateRijndael(password, salt);
sma.IV = IV;
value = 32;
long lSize = -1;
// 创建散列对象, 校验文件
HashAlgorithm hasher = SHA256.Create();
using (CryptoStream cin = new CryptoStream(fin, sma.CreateDecryptor(), CryptoStreamMode.Read),
chash = new CryptoStream(Stream.Null, hasher, CryptoStreamMode.Write))
{
// 读取文件长度
BinaryReader br = new BinaryReader(cin);
lSize = br.ReadInt64();
ulong tag = br.ReadUInt64();
if (FC_TAG != tag)
throw new Exception("文件被破坏");
long numReads = lSize / BUFFER_SIZE;
long slack = (long)lSize % BUFFER_SIZE;
for (int i = 0; i < numReads; ++i)
{
read = cin.Read(bytes, 0, bytes.Length);
fout.Write(bytes, 0, read);
chash.Write(bytes, 0, read);
value += read;
outValue += read;
}
if (slack > 0)
{
read = cin.Read(bytes, 0, (int)slack);
fout.Write(bytes, 0, read);
chash.Write(bytes, 0, read);
value += read;
outValue += read;
}
chash.Flush();
chash.Close();
fout.Flush();
fout.Close();
byte[] curHash = hasher.Hash;
// 获取比较和旧的散列对象
byte[] oldHash = new byte[hasher.HashSize / 8];
read = cin.Read(oldHash, 0, oldHash.Length);
if ((oldHash.Length != read) || (!CheckByteArrays(oldHash, curHash)))
throw new Exception("文件被破坏");
}
if (outValue != lSize)
throw new Exception("文件大小不匹配");
}
}
}
}

View File

@ -1,6 +1,6 @@
using System.Text;
namespace Zerolauncher.Manager
namespace Zerolauncher.util
{
class SpaceEncoder
{