Files
2026-08-27 10:56:38 -06:00

168 lines
4.2 KiB
C#

using System;
using System.IO;
using System.IO.Compression;
using System.Security.Cryptography;
namespace PureCrack.Crypto;
public static class Symmetric
{
public static readonly byte[] AesKey = HexToBytes("e6c43cc05d35fee7c8533d96203eeda357c65e85e30dbe622fad26fdfbb222a8");
public static byte[] AesEncrypt(byte[] plaintext, byte[] iv)
{
if (iv.Length != 16)
{
throw new ArgumentException("iv must be 16 bytes", "iv");
}
using Aes aes = Aes.Create() ?? throw new InvalidOperationException("Aes.Create returned null");
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
aes.KeySize = 256;
aes.Key = AesKey;
aes.IV = iv;
using ICryptoTransform cryptoTransform = aes.CreateEncryptor();
return cryptoTransform.TransformFinalBlock(plaintext, 0, plaintext.Length);
}
public static byte[] AesDecrypt(byte[] ciphertext, byte[] iv)
{
if (iv.Length != 16)
{
throw new ArgumentException("iv must be 16 bytes", "iv");
}
using Aes aes = Aes.Create() ?? throw new InvalidOperationException("Aes.Create returned null");
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
aes.KeySize = 256;
aes.Key = AesKey;
aes.IV = iv;
using ICryptoTransform cryptoTransform = aes.CreateDecryptor();
return cryptoTransform.TransformFinalBlock(ciphertext, 0, ciphertext.Length);
}
public static byte[] AesEncryptFraming(byte[] plaintext)
{
byte[] array = RandomBytes(16);
byte[] array2 = AesEncrypt(plaintext, array);
byte[] array3 = new byte[16 + array2.Length];
Buffer.BlockCopy(array, 0, array3, 0, 16);
Buffer.BlockCopy(array2, 0, array3, 16, array2.Length);
return array3;
}
public static byte[] AesDecryptFraming(byte[] framedBody)
{
if (framedBody.Length < 32)
{
throw new ArgumentException("framed body must be at least 32 bytes (IV + 1 block)");
}
byte[] array = new byte[16];
Buffer.BlockCopy(framedBody, 0, array, 0, 16);
byte[] array2 = new byte[framedBody.Length - 16];
Buffer.BlockCopy(framedBody, 16, array2, 0, array2.Length);
return AesDecrypt(array2, array);
}
public static byte[] TripleDesEncrypt(byte[] plaintext, byte[] key, byte[] iv)
{
if (key.Length != 24)
{
throw new ArgumentException("3DES key must be 24 bytes", "key");
}
if (iv.Length != 8)
{
throw new ArgumentException("3DES iv must be 8 bytes", "iv");
}
using TripleDES tripleDES = TripleDES.Create() ?? throw new InvalidOperationException("TripleDES.Create returned null");
tripleDES.Mode = CipherMode.CBC;
tripleDES.Padding = PaddingMode.PKCS7;
tripleDES.Key = key;
tripleDES.IV = iv;
using ICryptoTransform cryptoTransform = tripleDES.CreateEncryptor();
return cryptoTransform.TransformFinalBlock(plaintext, 0, plaintext.Length);
}
public static byte[] RandomBytes(int n)
{
byte[] array = new byte[n];
using RandomNumberGenerator randomNumberGenerator = RandomNumberGenerator.Create();
randomNumberGenerator.GetBytes(array);
return array;
}
public static byte[] Gzip(byte[] data)
{
using MemoryStream memoryStream = new MemoryStream();
using (GZipStream gZipStream = new GZipStream(memoryStream, CompressionLevel.Optimal, leaveOpen: true))
{
gZipStream.Write(data, 0, data.Length);
}
return memoryStream.ToArray();
}
public static byte[] HexToBytes(string hex)
{
if ((hex.Length & 1) != 0)
{
throw new ArgumentException("hex string must have even length", "hex");
}
byte[] array = new byte[hex.Length / 2];
for (int i = 0; i < array.Length; i++)
{
int num = HexNibble(hex[i * 2]);
int num2 = HexNibble(hex[i * 2 + 1]);
array[i] = (byte)((num << 4) | num2);
}
return array;
}
private static int HexNibble(char c)
{
switch (c)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return c - 48;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
return c - 97 + 10;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
return c - 65 + 10;
default:
throw new FormatException($"non-hex char: {c}");
}
}
public static bool ConstantTimeEquals(byte[] a, byte[] b)
{
if (a.Length != b.Length)
{
return false;
}
int num = 0;
for (int i = 0; i < a.Length; i++)
{
num |= a[i] ^ b[i];
}
return num == 0;
}
}