using IdentityShroud.Core.Contracts; using IdentityShroud.Core.Model; using IdentityShroud.Core.Security; namespace IdentityShroud.Core.Services; public class DataEncryptionService( IRealmContext realmContext, IDekEncryptionService dekCryptor) : IDataEncryptionService { // 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 IList? _deks = null; private IList GetDeks() { if (_deks is null) _deks = realmContext.GetDeks().Result; return _deks; } private RealmDek GetActiveDek() => GetDeks().Single(d => d.Active); private RealmDek GetKey(DekId id) => GetDeks().Single(d => d.Id == id); public byte[] Decrypt(EncryptedValue input) { var dek = GetKey(input.DekId); var key = dekCryptor.Decrypt(dek.KeyData); return Encryption.Decrypt(input.Value, key); } public EncryptedValue Encrypt(ReadOnlyMemory plain) { var dek = GetActiveDek(); var key = dekCryptor.Decrypt(dek.KeyData); byte[] cipher = Encryption.Encrypt(plain, key); return new (dek.Id, cipher); } }