astral-api/Astral.Tests/ServiceTests/CryptographyServiceTests.cs

118 lines
3.8 KiB
C#
Raw Permalink Normal View History

// <copyright file="CryptographyServiceTests.cs" company="alveus.dev">
// Copyright (c) alveus.dev. All rights reserved. Licensed under the MIT License.
// </copyright>
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;
/// <summary>
/// Tests for <see cref="ICryptographyService"/>.
/// </summary>
public class CryptographyServiceTests
{
private readonly CryptographyService _service;
/// <summary>
/// Initializes a new instance of the <see cref="CryptographyServiceTests"/> class.
/// </summary>
public CryptographyServiceTests()
{
var pwdHashOptions = new PwdHashOptions()
{
DegreeOfParallelism = 4,
HashSize = 128,
SaltSize = 64,
MemoryToUseKb = 16,
NumberOfIterations = 3
};
_service = new CryptographyService(
new OptionsWrapper<PwdHashOptions>(pwdHashOptions),
new NullLogger<CryptographyService>());
}
/// <summary>
/// Password hashing and verification tests.
/// </summary>
[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));
});
}
/// <summary>
/// Public key conversion tests.
/// </summary>
[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);
}
}