38 lines
No EOL
1.3 KiB
C#
38 lines
No EOL
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(ReadOnlySpan<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);
|
||
}
|
||
} |