patbef-ServiceOutside/ServiceOutside/Documents/Datenschutz-Audit/Crypto_Codes_with_Unittests/AES.txt

132 lines
4.5 KiB
Plaintext
Raw Permalink Normal View History

2024-01-29 16:27:34 +01:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace ServiceShared.Crypto
{
public static class AES
{
private static byte[] MemoryMasterKey = null;
/// <summary>
/// Sets the memory master key
/// </summary>
/// <param name="key">master key that should be set in the memory</param>
public static void SetMemoryMasterKey(byte[] deriveKey)
{
MemoryMasterKey = deriveKey;
}
/// <summary>
/// Encrypts string with password
/// </summary>
/// <param name="value">string value that should be encrypted</param>
/// <param name="deriveKey">shared deriveKey that should be used for encryption(max. 32 bytes)</param>
/// <returns>returns encrypted base64 string</returns>
public static string Encrypt(string value, byte[] deriveKey = null)
{
string result = null;
try
{
if (deriveKey == null)
{
deriveKey = MemoryMasterKey;
}
using (AesGcm aes = new AesGcm(deriveKey))
{
byte[] nonce = new byte[AesGcm.NonceByteSizes.MaxSize];
RandomNumberGenerator.Fill(nonce);
byte[] plainText = Encoding.UTF8.GetBytes(value);
byte[] chiperBuffer = new byte[plainText.Length];
byte[] tag = new byte[AesGcm.TagByteSizes.MaxSize];
aes.Encrypt(nonce, plainText, chiperBuffer, tag);
byte[] resultBuffer = nonce.Concat(chiperBuffer).Concat(tag).ToArray();
result = Convert.ToBase64String(resultBuffer);
}
}
catch
{
result = null;
}
return result;
}
/// <summary>
/// Decrypts encrypted base64 string with password
/// </summary>
/// <param name="value">base64 string that should be decrypted</param>
/// <param name="deriveKey">HKDF.DeriveKey of sharedSecret</param>
/// <returns>returns plain string</returns>
public static string Decrypt(string value, byte[] deriveKey = null)
{
string result = null;
try
{
if (deriveKey == null)
{
deriveKey = MemoryMasterKey;
}
if (!string.IsNullOrEmpty(value) && deriveKey != null && deriveKey.Length == 32)
{
using (AesGcm aes = new AesGcm(deriveKey))
{
byte[] combined = Convert.FromBase64String(value);
byte[] tag = combined.Skip(combined.Length - AesGcm.TagByteSizes.MaxSize).ToArray();
byte[] nonce = combined.Take(AesGcm.NonceByteSizes.MaxSize).ToArray();
byte[] chiperText = combined.Skip(nonce.Length).Take(combined.Length - nonce.Length - tag.Length).ToArray();
byte[] plainTextBuffer = new byte[chiperText.Length];
aes.Decrypt(nonce, chiperText, tag, plainTextBuffer);
result = Encoding.UTF8.GetString(plainTextBuffer);
}
}
}
catch
{
result = null;
}
return result;
}
/// <summary>
/// Converts the text passed password to the 32 byte array
/// </summary>
/// <param name="password">Text based password</param>
/// <returns></returns>
public static byte[] GetKey(string password)
{
byte[] result = null;
try
{
if (!string.IsNullOrEmpty(password))
{
if (password.Length < 32)
{
password = password.PadRight(32, '@');
}
else if (password.Length > 32)
{
password = MD5.Encrypt(password);
}
result = Encoding.ASCII.GetBytes(password);
}
}
catch (Exception ex)
{
Log.Critical(ex, "ServiceShared.Crypto.AES", "GetKey");
}
return result;
}
}
}