81 lines
2.5 KiB
C#
81 lines
2.5 KiB
C#
|
|
using System;
|
||
|
|
using System.IO;
|
||
|
|
using System.Security.Cryptography;
|
||
|
|
using System.Text;
|
||
|
|
|
||
|
|
namespace SNote.Server.Security;
|
||
|
|
|
||
|
|
public static class SecurityHelper
|
||
|
|
{
|
||
|
|
// Encrypts plaintext using AES-256 with a randomized IV, prepending IV to the ciphertext.
|
||
|
|
public static string Encrypt(string plaintext, string base64Key)
|
||
|
|
{
|
||
|
|
if (string.IsNullOrEmpty(plaintext)) return plaintext;
|
||
|
|
|
||
|
|
try
|
||
|
|
{
|
||
|
|
var keyBytes = Convert.FromBase64String(base64Key);
|
||
|
|
using var aes = Aes.Create();
|
||
|
|
aes.Key = keyBytes;
|
||
|
|
aes.GenerateIV();
|
||
|
|
var iv = aes.IV;
|
||
|
|
|
||
|
|
using var encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
|
||
|
|
using var ms = new MemoryStream();
|
||
|
|
|
||
|
|
// Prepend IV
|
||
|
|
ms.Write(iv, 0, iv.Length);
|
||
|
|
|
||
|
|
using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
|
||
|
|
using (var sw = new StreamWriter(cs, Encoding.UTF8))
|
||
|
|
{
|
||
|
|
sw.Write(plaintext);
|
||
|
|
}
|
||
|
|
|
||
|
|
return Convert.ToBase64String(ms.ToArray());
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
Console.WriteLine($"Encryption error: {ex.Message}");
|
||
|
|
return plaintext;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Decrypts ciphertext (which has prepended IV) using AES-256.
|
||
|
|
public static string Decrypt(string ciphertext, string base64Key)
|
||
|
|
{
|
||
|
|
if (string.IsNullOrEmpty(ciphertext)) return ciphertext;
|
||
|
|
|
||
|
|
try
|
||
|
|
{
|
||
|
|
var fullCipher = Convert.FromBase64String(ciphertext);
|
||
|
|
var keyBytes = Convert.FromBase64String(base64Key);
|
||
|
|
|
||
|
|
using var aes = Aes.Create();
|
||
|
|
aes.Key = keyBytes;
|
||
|
|
|
||
|
|
var iv = new byte[16];
|
||
|
|
var cipherTextBytes = new byte[fullCipher.Length - 16];
|
||
|
|
|
||
|
|
Buffer.BlockCopy(fullCipher, 0, iv, 0, 16);
|
||
|
|
Buffer.BlockCopy(fullCipher, 16, cipherTextBytes, 0, cipherTextBytes.Length);
|
||
|
|
|
||
|
|
aes.IV = iv;
|
||
|
|
|
||
|
|
using var decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
|
||
|
|
using var ms = new MemoryStream(cipherTextBytes);
|
||
|
|
using var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read);
|
||
|
|
using var sr = new StreamReader(cs, Encoding.UTF8);
|
||
|
|
|
||
|
|
return sr.ReadToEnd();
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
Console.WriteLine($"Decryption error: {ex.Message}. Returning ciphertext as-is.");
|
||
|
|
return ciphertext;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Server-to-server signing token or helper (optional, or we do JWTs)
|
||
|
|
}
|