38 lines
1.3 KiB
C#
38 lines
1.3 KiB
C#
|
|
using IdentityShroud.Core.Contracts;
|
|||
|
|
using IdentityShroud.Core.Security;
|
|||
|
|
|
|||
|
|
namespace IdentityShroud.Core.Services;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
///
|
|||
|
|
/// </summary>
|
|||
|
|
public class DekEncryptionService : IDekEncryptionService
|
|||
|
|
{
|
|||
|
|
// Note this array is expected to have one item in it most of the during key rotation it will have two
|
|||
|
|
// until it is ensured the old key can safely be removed. More then two will work but is not really expected.
|
|||
|
|
private readonly KeyEncryptionKey[] _encryptionKeys;
|
|||
|
|
|
|||
|
|
private KeyEncryptionKey ActiveKey => _encryptionKeys.Single(k => k.Active);
|
|||
|
|
private KeyEncryptionKey GetKey(KekId keyId) => _encryptionKeys.Single(k => k.Id == keyId);
|
|||
|
|
|
|||
|
|
public DekEncryptionService(ISecretProvider secretProvider)
|
|||
|
|
{
|
|||
|
|
_encryptionKeys = secretProvider.GetKeys("master");
|
|||
|
|
// if (_encryptionKey.Length != 32) // 256‑bit key
|
|||
|
|
// throw new Exception("Key must be 256 bits (32 bytes) for AES‑256‑GCM.");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public EncryptedDek Encrypt(ReadOnlyMemory<byte> plaintext)
|
|||
|
|
{
|
|||
|
|
var encryptionKey = ActiveKey;
|
|||
|
|
byte[] cipher = Encryption.Encrypt(plaintext, encryptionKey.Key);
|
|||
|
|
return new (encryptionKey.Id, cipher);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public byte[] Decrypt(EncryptedDek input)
|
|||
|
|
{
|
|||
|
|
var encryptionKey = GetKey(input.KekId);
|
|||
|
|
|
|||
|
|
return Encryption.Decrypt(input.Value, encryptionKey.Key);
|
|||
|
|
}
|
|||
|
|
}
|