lampac-talks f843f04fd4 chore: initial commit 154.3
Signed-off-by: lampac-talks <lampac-talks@users.noreply.github.com>
2026-01-30 16:23:09 +03:00

119 lines
3.9 KiB
C#

using System.Security.Cryptography;
using System.Text;
using System.Threading;
namespace Shared.Engine
{
public static class AesTo
{
static byte[] aesKey, aesIV;
static readonly ThreadLocal<ThreadState> tls = new(() => new ThreadState());
static AesTo()
{
if (File.Exists("cache/aeskey"))
{
var i = File.ReadAllText("cache/aeskey").Split("/");
aesKey = Encoding.UTF8.GetBytes(i[0]);
aesIV = Encoding.UTF8.GetBytes(i[1]);
}
else
{
string k = CrypTo.unic(16);
string v = CrypTo.unic(16);
File.WriteAllText("cache/aeskey", $"{k}/{v}");
aesKey = Encoding.UTF8.GetBytes(k);
aesIV = Encoding.UTF8.GetBytes(v);
}
}
public static string Encrypt(string plainText)
{
if (string.IsNullOrWhiteSpace(plainText))
return plainText;
try
{
var state = tls.Value;
var aes = state.Aes;
int writtenPlain = Encoding.UTF8.GetBytes(plainText, 0, plainText.Length, state.encryptPlain, 0);
int blockSize = aes.BlockSize / 8; // 16
int paddedLen = ((writtenPlain / blockSize) + 1) * blockSize;
if (paddedLen > state.encryptCipherBuf.Length)
return plainText;
// ВАЖНО: iv вторым параметром, destination третьим
int cipherLen = aes.EncryptCbc(
state.encryptPlain.AsSpan(0, writtenPlain),
aesIV, // iv (16 байт)
state.encryptCipherBuf.AsSpan(0, paddedLen), // destination
PaddingMode.PKCS7);
if (!Convert.TryToBase64Chars(state.encryptCipherBuf.AsSpan(0, cipherLen), state.encryptBase64Chars, out int charsWritten))
return plainText;
return new string(state.encryptBase64Chars, 0, charsWritten);
}
catch
{
return plainText;
}
}
public static string Decrypt(ReadOnlySpan<char> cipherText)
{
if (cipherText.IsEmpty)
return null;
try
{
var state = tls.Value;
var aes = state.Aes;
if (!Convert.TryFromBase64Chars(cipherText, state.decryptCipherBuf, out int cipherLen))
return null;
// ВАЖНО: iv вторым параметром, destination третьим
int plainLen = aes.DecryptCbc(
state.decryptCipherBuf.AsSpan(0, cipherLen),
aesIV, // iv (16 байт)
state.decryptPlain.AsSpan(0, cipherLen), // destination
PaddingMode.PKCS7);
return Encoding.UTF8.GetString(state.decryptPlain, 0, plainLen);
}
catch
{
return null;
}
}
private sealed class ThreadState
{
public readonly Aes Aes;
public char[] encryptBase64Chars = new char[PoolInvk.rentLargeChunk];
public byte[] encryptCipherBuf = new byte[PoolInvk.rentLargeChunk];
public byte[] encryptPlain = new byte[PoolInvk.rentLargeChunk];
public byte[] decryptCipherBuf = new byte[PoolInvk.rentLargeChunk];
public byte[] decryptPlain = new byte[PoolInvk.rentLargeChunk];
public ThreadState()
{
Aes = Aes.Create();
Aes.Mode = CipherMode.CBC;
Aes.Padding = PaddingMode.PKCS7;
Aes.Key = aesKey;
Aes.IV = aesIV;
}
}
}
}