Elisa/Elisa.Common/Utils/Crypto.cs

254 lines
6.7 KiB
C#
Raw Permalink Normal View History

using ICSharpCode.SharpZipLib.GZip;
using System.IO.Compression;
using System.Security.Cryptography;
using System.Text;
namespace Elisa.Common.Utils;
public static class Crypto
{
static DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
static MD5 md5 = System.Security.Cryptography.MD5.Create();
public static string Decrypt(string body, string key)
{
if (string.IsNullOrEmpty(body) || string.IsNullOrEmpty(key))
return string.Empty;
if (body.Length == 1 || body.StartsWith("error:") || body.StartsWith("{") && body.EndsWith("}"))
return body;
try
{
string text = MD5(MD5(key).Substring(16));
string pwd = text + MD5(text);
if (body.StartsWith("#"))
{
body = body.Substring(1);
return GZipDecompress(RC4(ConvertFromBase64String(body), pwd).Skip(26).ToArray());
}
byte[] bytes = RC4(ConvertFromBase64String(body), pwd);
string @string = Encoding.UTF8.GetString(bytes);
return @string.Length > 26 ? @string.Substring(26) : string.Empty;
}
catch
{
}
return string.Empty;
}
public static string Encrypt(string body, string key)
{
try
{
byte[] array = GZipCompress(Encoding.UTF8.GetBytes(body));
string text = MD5(key);
string s = MD5(text.Substring(0, 16));
string text2 = MD5(text.Substring(16, 16));
string pwd = text2 + MD5(text2);
byte[] bytes = Encoding.UTF8.GetBytes(string.Format("{0}", Math.Round(GetCurrentSec()) + 3600.0));
string s2 = MD5(array.Concat(Encoding.UTF8.GetBytes(s)).ToArray()).Substring(0, 16);
byte[] array2 = new byte[array.Length + 26];
Array.Copy(bytes, 0, array2, 0, bytes.Length);
Array.Copy(Encoding.UTF8.GetBytes(s2), 0, array2, 10, 16);
Array.Copy(array, 0, array2, 26, array.Length);
return "#" + Convert.ToBase64String(RC4(array2, pwd));
}
catch
{
}
return string.Empty;
}
public static byte[] ConvertFromBase64String(string input)
{
byte[] result = [];
try
{
result = Convert.FromBase64String(input);
}
catch
{
try
{
result = Convert.FromBase64String(input + "=");
}
catch
{
try
{
result = Convert.FromBase64String(input + "==");
}
catch
{
return result;
}
}
}
return result;
}
public static double GetCurrentSec()
{
return (DateTime.UtcNow - epoch).TotalSeconds;
}
public static string MD5(string input)
{
return MD5(Encoding.UTF8.GetBytes(input));
}
public static string MD5(byte[] input)
{
byte[] array = md5.ComputeHash(input);
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < array.Length; i++)
stringBuilder.Append(array[i].ToString("x2"));
return stringBuilder.ToString();
}
public static byte[] RC4(byte[] data, string pwd)
{
return RC4(data, Encoding.UTF8.GetBytes(pwd));
}
public static byte[] RC4(byte[] data, byte[] pwd)
{
int[] array = new int[256];
int[] array2 = new int[256];
byte[] array3 = new byte[data.Length];
int i;
int num;
for (i = 0; i < 256; i++)
{
array[i] = pwd[i % pwd.Length];
array2[i] = i;
}
for (i = num = 0; i < 256; i++)
{
int num2 = array2[i];
num = (num + array2[i] + array[i]) % 256;
array2[i] = array2[num];
array2[num] = num2;
}
int num3;
num = num3 = i = 0;
while (i < data.Length)
{
num3++;
num3 %= 256;
num += array2[num3];
num %= 256;
int num2 = array2[num3];
array2[num3] = array2[num];
array2[num] = num2;
int num4 = array2[(array2[num3] + array2[num]) % 256];
array3[i] = (byte)(data[i] ^ num4);
i++;
}
return array3;
}
public static byte[] GZipCompress(byte[] raw)
{
byte[] result;
using (MemoryStream memoryStream = new MemoryStream())
{
using GZipOutputStream gzipOutputStream = new GZipOutputStream(memoryStream);
gzipOutputStream.IsStreamOwner = false;
gzipOutputStream.Write(raw, 0, raw.Length);
gzipOutputStream.Flush();
gzipOutputStream.Finish();
result = memoryStream.ToArray();
}
return result;
}
public static string GZipDecompress(byte[] raw)
{
string result;
using (MemoryStream memoryStream = new MemoryStream(raw))
{
using Stream stream = new GZipInputStream(memoryStream);
using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8);
result = streamReader.ReadToEnd();
}
return result;
}
public static string CompressText(string text)
{
byte[] bytes = Encoding.UTF8.GetBytes(text);
byte[]? inArray = null;
using (MemoryStream memoryStream = new MemoryStream())
{
using (GZipStream gzipStream = new GZipStream(memoryStream, CompressionMode.Compress))
{
gzipStream.Write(bytes, 0, bytes.Length);
}
inArray = memoryStream.ToArray();
}
return Convert.ToBase64String(inArray);
}
public static string DecompressText(string text)
{
string result = string.Empty;
using (MemoryStream memoryStream = new MemoryStream(Convert.FromBase64String(text)))
{
using (GZipStream gzipStream = new GZipStream(memoryStream, CompressionMode.Decompress))
{
using (StreamReader streamReader = new StreamReader(gzipStream))
{
result = streamReader.ReadToEnd();
}
}
}
return result;
}
public static string ConvertMD5(string input)
{
byte[] array = md5.ComputeHash(Encoding.UTF8.GetBytes(input));
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < array.Length; i++)
stringBuilder.Append(array[i].ToString("x2"));
return stringBuilder.ToString();
}
}