2026-02-27 17:57:42 +00:00
|
|
|
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");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public EncryptedDek Encrypt(ReadOnlySpan<byte> plaintext)
|
|
|
|
|
{
|
|
|
|
|
var encryptionKey = ActiveKey;
|
|
|
|
|
byte[] cipher = Encryption.Encrypt(plaintext, encryptionKey.Key);
|
|
|
|
|
return new (encryptionKey.Id, cipher);
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-18 07:40:24 +02:00
|
|
|
public void Decrypt(EncryptedDek input, Span<byte> output)
|
2026-02-27 17:57:42 +00:00
|
|
|
{
|
|
|
|
|
var encryptionKey = GetKey(input.KekId);
|
2026-08-18 07:40:24 +02:00
|
|
|
Encryption.Decrypt(input.Value, encryptionKey.Key, output);
|
|
|
|
|
}
|
2026-02-27 17:57:42 +00:00
|
|
|
|
2026-08-18 07:40:24 +02:00
|
|
|
public int GetDecryptedSize(EncryptedDek input)
|
|
|
|
|
{
|
|
|
|
|
return Encryption.GetDecryptedLength(input.Value);
|
2026-02-27 17:57:42 +00:00
|
|
|
}
|
|
|
|
|
}
|