//
// Copyright (c) alveus.dev. All rights reserved. Licensed under the MIT License.
//
using Astral.Services.Constants;
using Astral.Services.Interfaces;
using Astral.Services.Options;
using Astral.Services.Services;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
namespace Astral.Tests.ServiceTests;
///
/// Tests for .
///
public class CryptographyServiceTests
{
private readonly CryptographyService _service;
///
/// Initializes a new instance of the class.
///
public CryptographyServiceTests()
{
var pwdHashOptions = new PwdHashOptions()
{
DegreeOfParallelism = 4,
HashSize = 128,
SaltSize = 64,
MemoryToUseKb = 16,
NumberOfIterations = 3
};
_service = new CryptographyService(
new OptionsWrapper(pwdHashOptions),
new NullLogger());
}
///
/// Password hashing and verification tests.
///
[Fact]
public void HashingAndVerificationTests()
{
const string password = "Password1234!";
const string badPassword = "Password123!";
var salt1 = _service.GenerateSalt();
var salt2 = _service.GenerateSalt();
var salt3 = _service.GenerateSalt();
var hash1 = _service.HashPassword(password, salt1);
var hash2 = _service.HashPassword(password, salt2);
var hash3 = _service.HashPassword(password, salt3);
Assert.Multiple(() =>
{
Assert.NotNull(hash1);
Assert.NotNull(hash2);
Assert.NotNull(hash3);
});
// Ensure unique hashes.
Assert.Multiple(() =>
{
Assert.NotEqual(hash1, hash2);
Assert.NotEqual(hash1, hash3);
Assert.NotEqual(hash2, hash3);
});
// Ensure passwords can be verified.
Assert.Multiple(() =>
{
Assert.True(_service.VerifyPassword(password, salt1, hash1));
Assert.True(_service.VerifyPassword(password, salt2, hash2));
Assert.True(_service.VerifyPassword(password, salt3, hash3));
});
// Ensure bad password/hash combinations do not get verified.
Assert.Multiple(() =>
{
Assert.False(_service.VerifyPassword(password, salt1, hash2));
Assert.False(_service.VerifyPassword(password, salt1, hash3));
Assert.False(_service.VerifyPassword(password, salt2, hash1));
Assert.False(_service.VerifyPassword(password, salt2, hash3));
Assert.False(_service.VerifyPassword(password, salt3, hash1));
Assert.False(_service.VerifyPassword(password, salt3, hash2));
});
// Ensure bad password do not get verified.
Assert.Multiple(() =>
{
Assert.False(_service.VerifyPassword(badPassword, salt1, hash1));
Assert.False(_service.VerifyPassword(badPassword, salt2, hash2));
Assert.False(_service.VerifyPassword(badPassword, salt3, hash3));
});
}
///
/// Public key conversion tests.
///
[Fact]
public async Task PublicKeyConversionTests()
{
var publicKeyDer = await File.ReadAllBytesAsync("./TestData/public-key.der");
var publicKeyPem = await File.ReadAllTextAsync("./TestData/public-key.pem");
publicKeyPem = _service.SimplifyPemKey(publicKeyPem);
var generatedPem = _service.ConvertPublicKey(publicKeyDer, PublicKeyType.SpkiX509PublicKey);
generatedPem = _service.SimplifyPemKey(generatedPem);
Assert.Equal(generatedPem, publicKeyPem);
}
}