Skip to content

Commit

Permalink
Random password Update
Browse files Browse the repository at this point in the history
  • Loading branch information
Haik committed Oct 16, 2023
1 parent 82427bd commit 28813e8
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 67 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace Pandatech.Crypto.Tests;

public class UnitTests
public class Aes256Tests
{
[Fact]
public void Generate_ShouldReturnByteArray()
Expand All @@ -12,52 +12,7 @@ public void Generate_ShouldReturnByteArray()
Assert.Equal(length, randomBytes.Length);
}

[Theory]
[InlineData(100, true, true, true, true)]
[InlineData(10, false, true, false, false)]
[InlineData(50, true, true, true, false)]
public void Generate_ShouldReturnPasswordWithCorrectProperties(
int length,
bool includeUppercase,
bool includeLowercase,
bool includeDigits,
bool includeSpecialChars)
{
// Generate a random password
var password = RandomPassword.Generate(length, includeUppercase, includeLowercase, includeDigits,
includeSpecialChars);

// Check if the password length is correct
Assert.Equal(length, password.Length);

// Check if the password contains the correct character sets
if (includeUppercase)
Assert.Contains(password, char.IsUpper);
if (includeLowercase)
Assert.Contains(password, char.IsLower);
if (includeDigits)
Assert.Contains(password, char.IsDigit);
if (includeSpecialChars)
Assert.Contains(password, c => "!@#$%^&*()-_=+[]{}|;:'\",.<>?".Contains(c));
}

[Fact]
public void Generate_ShouldReturnDifferentPasswords()
{
var password1 = RandomPassword.Generate(12, true, true, true, true);
var password2 = RandomPassword.Generate(12, true, true, true, true);

Assert.NotEqual(password1, password2);
}

[Fact]
public void HashVerify_ShouldBeValid()
{
var password = RandomPassword.Generate(32, true, true, true, true);
var hash = Argon2Id.HashPassword(password);

Assert.True(Argon2Id.VerifyHash(password, hash));
}


[Fact]
public void EncryptDecryptWithParameter_ShouldReturnOriginalString()
Expand Down Expand Up @@ -119,15 +74,5 @@ public void EncryptDecryptWithNullCipher_ShouldThrowException()
Assert.Throws<ArgumentException>(() => Aes256.Decrypt(null!, key));
}

[Fact]
public void HashPassword_EmptyPassword_ShouldThrowException()
{
Assert.Throws<ArgumentException>(() => Argon2Id.HashPassword(""));
}

[Fact]
public void VerifyHash_NullHash_ShouldThrowException()
{
Assert.Throws<ArgumentException>(() => Argon2Id.VerifyHash("password", null!));
}

}
45 changes: 45 additions & 0 deletions Pandatech.Crypto.Tests/Argon2IdTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
namespace Pandatech.Crypto.Tests;

public class Argon2IdTests
{
[Fact]
public void HashVerify_ShouldBeValid()
{
var password = RandomPassword.Generate(32, true, true, true, true);
var hash = Argon2Id.HashPassword(password);

Assert.True(Argon2Id.VerifyHash(password, hash));
}

[Fact]
public void HashVerify_InvalidPassword_ShouldBeInvalid()
{
var password = RandomPassword.Generate(32, true, true, true, true);
var hash = Argon2Id.HashPassword(password);


}

[Fact]
public void DifferentPasswords_ShouldHaveDifferentHashes()
{
var password1 = RandomPassword.Generate(32, true, true, true, true);
var password2 = RandomPassword.Generate(32, true, true, true, true);
var hash1 = Argon2Id.HashPassword(password1);
var hash2 = Argon2Id.HashPassword(password2);

Assert.NotEqual(hash1, hash2);
}

[Fact]
public void HashPassword_EmptyPassword_ShouldThrowException()
{
Assert.Throws<ArgumentException>(() => Argon2Id.HashPassword(""));
}

[Fact]
public void VerifyHash_NullHash_ShouldThrowException()
{
Assert.Throws<ArgumentException>(() => Argon2Id.VerifyHash("password", null!));
}
}
42 changes: 42 additions & 0 deletions Pandatech.Crypto.Tests/RandomPasswordTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
namespace Pandatech.Crypto.Tests;

public class RandomPasswordTests
{
[Theory]
[InlineData(7, true, true, true, true)]
[InlineData(4, false, true, false, false)]
[InlineData(5, true, true, true, false)]
public void Generate_ShouldReturnPasswordWithCorrectProperties(
int length,
bool includeUppercase,
bool includeLowercase,
bool includeDigits,
bool includeSpecialChars)
{
// Generate a random password
var password = RandomPassword.Generate(length, includeUppercase, includeLowercase, includeDigits,
includeSpecialChars);

// Check if the password length is correct
Assert.Equal(length, password.Length);

// Check if the password contains the correct character sets
if (includeUppercase)
Assert.Contains(password, char.IsUpper);
if (includeLowercase)
Assert.Contains(password, char.IsLower);
if (includeDigits)
Assert.Contains(password, char.IsDigit);
if (includeSpecialChars)
Assert.Contains(password, c => "!@#$%^&*()-_=+[]{}|;:'\",.<>?".Contains(c));
}

[Fact]
public void Generate_ShouldReturnDifferentPasswords()
{
var password1 = RandomPassword.Generate(12, true, true, true, true);
var password2 = RandomPassword.Generate(12, true, true, true, true);

Assert.NotEqual(password1, password2);
}
}
4 changes: 2 additions & 2 deletions Pandatech.Crypto/Pandatech.Crypto.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Version>1.1.1</Version>
<Version>1.1.2</Version>
<Title>Pandatech.Crypto</Title>
<Authors>Pandatech</Authors>
<PackageIcon>pandatech.png</PackageIcon>
<PackageReadmeFile>Readme.md</PackageReadmeFile>
<Description>PandaTech.Crypto is a .NET library simplifying common cryptograhic functions.</Description>
<RepositoryUrl>https://github.com/PandaTechAM/be-lib-pandatech-crypto</RepositoryUrl>
<PackageReleaseNotes>Refactoring project</PackageReleaseNotes>
<PackageReleaseNotes>Refactored RandomPassword class logic</PackageReleaseNotes>
</PropertyGroup>

<ItemGroup>
Expand Down
62 changes: 55 additions & 7 deletions Pandatech.Crypto/RandomPassword.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,18 @@ public static class RandomPassword
public static string Generate(int length, bool includeUppercase, bool includeLowercase, bool includeDigits,
bool includeSpecialChars)
{
if (length <= 0)
throw new ArgumentException("Password length must be greater than zero.");
var typesCount = (includeUppercase ? 1 : 0) + (includeLowercase ? 1 : 0) + (includeDigits ? 1 : 0) +
(includeSpecialChars ? 1 : 0);

if (typesCount == 0)
{
throw new ArgumentException("At least one character set must be selected.");
}

if (length < typesCount)
{
throw new ArgumentException($"Password length must be at least {typesCount}.");
}

var charSet = "";
if (includeUppercase)
Expand All @@ -23,18 +33,56 @@ public static string Generate(int length, bool includeUppercase, bool includeLow
if (includeSpecialChars)
charSet += SpecialChars;

if (string.IsNullOrEmpty(charSet))
throw new ArgumentException("At least one character set must be selected.");

var buffer = Random.GenerateBytes(length);
var buffer = Random.GenerateBytes(length - typesCount);
var requiredBuffer = Random.GenerateBytes(typesCount);

var password = new char[length];
for (var i = 0; i < length; i++)
for (var i = 0; i < buffer.Length; i++)
{
var index = buffer[i] % charSet.Length;
password[i] = charSet[index];
}

return new string(password);
var bufferIndex = 0;

if (includeUppercase)
{
var index = requiredBuffer[bufferIndex++] % UppercaseChars.Length;
password[buffer.Length + bufferIndex - 1] = UppercaseChars[index];
}

if (includeLowercase)
{
var index = requiredBuffer[bufferIndex++] % LowercaseChars.Length;
password[buffer.Length + bufferIndex - 1] = LowercaseChars[index];
}

if (includeDigits)
{
var index = requiredBuffer[bufferIndex++] % DigitChars.Length;
password[buffer.Length + bufferIndex - 1] = DigitChars[index];
}

if (includeSpecialChars)
{
var index = requiredBuffer[bufferIndex++] % SpecialChars.Length;
password[buffer.Length + bufferIndex - 1] = SpecialChars[index];
}

return ShuffleString(password);
}

private static string ShuffleString(char[] array)
{
var n = array.Length;
var randomBuffer = Random.GenerateBytes(n);

for (var i = n - 1; i >= 1; i--)
{
var j = randomBuffer[i] % (i + 1);
(array[i], array[j]) = (array[j], array[i]);
}
return new string(array);
}
}

0 comments on commit 28813e8

Please sign in to comment.