53 lines
1.3 KiB
C#
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);
|
|
}
|
|
}
|