feat: implement static key provider

This commit is contained in:
Stevan Freeborn
2026-04-01 12:45:57 -05:00
parent 25d13bb24b
commit f69317efe5
2 changed files with 76 additions and 0 deletions
@@ -0,0 +1,37 @@
namespace StevanFreeborn.Extensions.Configuration.Secure.Cryptography;
internal sealed class StaticKeyProvider : IEncryptionKeyProvider
{
private readonly byte[] _key;
public StaticKeyProvider(string base64Key)
{
if (string.IsNullOrWhiteSpace(base64Key))
{
throw new ArgumentNullException(nameof(base64Key));
}
byte[] decodedKey;
try
{
decodedKey = Convert.FromBase64String(base64Key);
}
catch (FormatException ex)
{
throw new ArgumentException("The provided key is not a valid Base64 string.", nameof(base64Key), ex);
}
if (decodedKey.Length != 32)
{
throw new ArgumentException("The encryption key must be exactly 32 bytes (256 bits) for AES-256 encryption.", nameof(base64Key));
}
_key = decodedKey;
}
public byte[] GetKey()
{
return _key;
}
}
@@ -0,0 +1,39 @@
using StevanFreeborn.Extensions.Configuration.Secure.Cryptography;
namespace StevanFreeborn.Extensions.Configuration.Secure.Tests.Unit.Cryptography;
public class StaticKeyProviderTests
{
[Fact]
public void Constructor_ShouldThrowArgumentNullException_WhenKeyIsNull()
{
var act = () => new StaticKeyProvider(null!);
act.Should().Throw<ArgumentNullException>();
}
[Fact]
public void Constructor_WhenCalledAndKeyIsNot32Bytes_ItShouldThrowArgumentException()
{
var shortKey = Convert.ToBase64String(new byte[16]);
var act = () => new StaticKeyProvider(shortKey);
act.Should().Throw<ArgumentException>().WithMessage("*must be exactly 32 bytes*");
}
[Fact]
public void GetKey_WhenCalled_ItShouldReturnValid32ByteArray()
{
var expectedBytes = new byte[32];
Random.Shared.NextBytes(expectedBytes);
var base64Key = Convert.ToBase64String(expectedBytes);
var provider = new StaticKeyProvider(base64Key);
var result = provider.GetKey();
result.Should().BeEquivalentTo(expectedBytes);
result.Length.Should().Be(32);
}
}