app/BTCPayApp.Core/Backup/SingleKeyDataProtector.cs
2025-01-23 19:02:35 +01:00

53 lines
1.3 KiB
C#

using System.Security.Cryptography;
using System.Text;
using Microsoft.AspNetCore.DataProtection;
namespace BTCPayApp.Core.Backup;
public class SingleKeyDataProtector : IDataProtector
{
private readonly byte[] _key;
public SingleKeyDataProtector(byte[] key)
{
if (key.Length != 32) // AES-256 key size
throw new ArgumentException("Key length must be 32 bytes.");
_key = key;
}
public IDataProtector CreateProtector(string purpose)
{
using var hmac = new HMACSHA256(_key);
var purposeBytes = Encoding.UTF8.GetBytes(purpose);
var key = hmac.ComputeHash(purposeBytes).Take(32).ToArray();
return new SingleKeyDataProtector(key);
}
public byte[] Protect(byte[] plaintext)
{
using var aes = Aes.Create();
aes.Key = _key;
aes.GenerateIV();
var iv = aes.IV;
var encrypted = aes.EncryptCbc(plaintext, iv);
return iv.Concat(encrypted).ToArray();
}
public byte[] Unprotect(byte[] protectedData)
{
using var aes = Aes.Create();
aes.Key = _key;
if (protectedData.Length == 0)
return protectedData;
var iv = protectedData.Take(16).ToArray();
var cipherText = protectedData.Skip(16).ToArray();
return aes.DecryptCbc(cipherText, iv);
}
}