Files
voice-cat/dotnet/tests/VoiceCat.Tests/PasswordTests.cs
T

43 lines
1.7 KiB
C#

using System.Text;
using System.Text.Json;
using VoiceCat.Crypto;
namespace VoiceCat.Tests;
public sealed class PasswordTests
{
[Fact]
public void VerifiesLibsodiumHashesWithoutPasswordNormalization()
{
var hasher = new PasswordHasher();
using var fixture = JsonDocument.Parse(File.ReadAllText(Path.Combine(AppContext.BaseDirectory, "Fixtures", "cpp-passwords.json")));
foreach (var item in fixture.RootElement.GetProperty("hashes").EnumerateArray())
{
string encodedPassword = item.GetProperty("passwordBase64").GetString()!;
string password = Encoding.UTF8.GetString(Convert.FromBase64String(encodedPassword.PadRight((encodedPassword.Length + 3) / 4 * 4, '=')));
string hash = item.GetProperty("hash").GetString()!;
Assert.True(hasher.Verify(password, hash));
Assert.False(hasher.Verify(password + "!", hash));
}
}
[Fact]
public void FreshHashesUseRandomSaltAndNativePhcFormat()
{
var hasher = new PasswordHasher();
string first = hasher.Hash("hello");
string second = hasher.Hash("hello");
Assert.NotEqual(first, second);
Assert.StartsWith("$argon2id$v=19$m=65536,t=2,p=1$", first);
Assert.True(hasher.Verify("hello", first));
Assert.False(hasher.Verify("wrong", first));
}
[Theory]
[InlineData("$argon2id$v=19$m=999999999,t=2,p=1$c2FsdA$aGFzaA")]
[InlineData("$argon2id$v=19$m=65536,t=99999,p=1$c2FsdA$aGFzaA")]
[InlineData("$argon2id$v=16$m=65536,t=2,p=1$c2FsdA$aGFzaA")]
[InlineData("$argon2id$v=19$m=65536,t=2,p=1$!!!$!!!")]
public void MalformedOrExcessiveHashesFailClosed(string hash) => Assert.False(new PasswordHasher().Verify("hello", hash));
}