98 lines
2.9 KiB
C#
98 lines
2.9 KiB
C#
#region copyright
|
|
// ------------------------------------------------------
|
|
// Copyright (C) Dmitriy Yukhanov [https://codestage.net]
|
|
// ------------------------------------------------------
|
|
#endregion
|
|
|
|
namespace CodeStage.AntiCheat.Utils
|
|
{
|
|
using System;
|
|
using System.IO;
|
|
using System.Security.Cryptography;
|
|
|
|
internal static class CryptoUtils
|
|
{
|
|
private const int BufferSize = 81920;
|
|
private const byte Iterations = 10;
|
|
|
|
private const byte AesSaltLengthBytes = 16;
|
|
private const byte AesKeyLengthBytes = 16;
|
|
|
|
private const byte Rc2SaltLengthBytes = 8;
|
|
private const byte Rc2KeyLengthBytes = 7;
|
|
|
|
public static void EncryptAes(Stream input, Stream output, byte[] password)
|
|
{
|
|
EncryptInternal<AesCryptoServiceProvider>(input, output, password, AesKeyLengthBytes);
|
|
}
|
|
|
|
public static void DecryptAes(Stream input, Stream output, byte[] password)
|
|
{
|
|
DecryptInternal<AesCryptoServiceProvider>(input, output, password, AesKeyLengthBytes, AesSaltLengthBytes);
|
|
}
|
|
|
|
public static void EncryptRc2(Stream input, Stream output, byte[] password)
|
|
{
|
|
EncryptInternal<RC2CryptoServiceProvider>(input, output, password, Rc2KeyLengthBytes);
|
|
}
|
|
|
|
public static void DecryptRc2(Stream input, Stream output, byte[] password)
|
|
{
|
|
DecryptInternal<RC2CryptoServiceProvider>(input, output, password, Rc2KeyLengthBytes, Rc2SaltLengthBytes);
|
|
}
|
|
|
|
private static void EncryptInternal<T>(Stream input, Stream output, byte[] password, byte keyLength) where T : SymmetricAlgorithm, new()
|
|
{
|
|
using (var crypto = new T())
|
|
{
|
|
crypto.GenerateIV();
|
|
var salt = crypto.IV;
|
|
|
|
using (var key = new Rfc2898DeriveBytes(password, salt, Iterations))
|
|
{
|
|
crypto.Key = key.GetBytes(keyLength);
|
|
}
|
|
|
|
output.Write(salt, 0, salt.Length);
|
|
|
|
using (var encryptor = crypto.CreateEncryptor())
|
|
{
|
|
using (var cryptoStream = new CryptoStream(output, encryptor, CryptoStreamMode.Write))
|
|
{
|
|
input.CopyTo(cryptoStream, BufferSize);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void DecryptInternal<T>(Stream input, Stream output, byte[] password, byte keyLength, byte saltLength) where T : SymmetricAlgorithm, new()
|
|
{
|
|
try
|
|
{
|
|
using (var crypto = new T())
|
|
{
|
|
var salt = new byte[saltLength];
|
|
input.Read(salt, 0, saltLength);
|
|
crypto.IV = salt;
|
|
|
|
using (var key = new Rfc2898DeriveBytes(password, salt, Iterations))
|
|
{
|
|
crypto.Key = key.GetBytes(keyLength);
|
|
}
|
|
|
|
using(var decryptor = crypto.CreateDecryptor())
|
|
{
|
|
using (var cryptoStream = new CryptoStream(input, decryptor, CryptoStreamMode.Read))
|
|
{
|
|
cryptoStream.CopyTo(output, BufferSize);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
throw new CryptographicException("Something went wrong while trying to decrypt data!", e);
|
|
}
|
|
}
|
|
}
|
|
} |