aegis-api/Aegis.Infrastructure/Crypto/AesGcmLabelCrypto.cs

55 lines
1.6 KiB
C#

using System.Security.Cryptography;
using System.Text;
using Aegis.Application.Abstractions;
namespace Aegis.Repository.Crypto;
public class AesGcmLabelCrypto : ILabelCrypto
{
private readonly ILabelKeyProvider _keys;
private const int TagSize = 16;
public AesGcmLabelCrypto(ILabelKeyProvider keys)
=> _keys = keys;
public string DecryptDatastoreName(
byte[] nameEnc,
byte[] nameNonce,
string lkKid,
int lkVersion,
string aad)
{
var key = _keys.GetLabelKey(lkKid, lkVersion);
try
{
return DecryptUtf8AesGcm(key, nameEnc, nameNonce, Encoding.UTF8.GetBytes(aad));
}
finally
{
CryptographicOperations.ZeroMemory(key);
}
}
private static string DecryptUtf8AesGcm(byte[] key, byte[] cipherWithTag, byte[] nonce, byte[] aad)
{
if (cipherWithTag.Length < TagSize)
throw new CryptographicException("Ciphertext inválido.");
var cipherLen = cipherWithTag.Length - TagSize;
var ciphertext = new byte[cipherLen];
var tag = new byte[TagSize];
Buffer.BlockCopy(cipherWithTag, 0, ciphertext, 0, cipherLen);
Buffer.BlockCopy(cipherWithTag, cipherLen, tag, 0, TagSize);
var plaintext = new byte[cipherLen];
using var aead = new AesGcm(key);
aead.Decrypt(nonce, ciphertext, tag, plaintext, aad);
var text = Encoding.UTF8.GetString(plaintext);
CryptographicOperations.ZeroMemory(plaintext);
CryptographicOperations.ZeroMemory(ciphertext);
CryptographicOperations.ZeroMemory(tag);
return text;
}
}