55 lines
1.6 KiB
C#
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;
|
|
}
|
|
} |