41 lines
1.3 KiB
C#
41 lines
1.3 KiB
C#
|
|
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<RealmDek>? _deks = null;
|
||
|
|
|
||
|
|
private IList<RealmDek> 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(ReadOnlySpan<byte> plain)
|
||
|
|
{
|
||
|
|
var dek = GetActiveDek();
|
||
|
|
var key = dekCryptor.Decrypt(dek.KeyData);
|
||
|
|
byte[] cipher = Encryption.Encrypt(plain, key);
|
||
|
|
return new (dek.Id, cipher);
|
||
|
|
}
|
||
|
|
}
|