Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide Argon2id overloads to pass password hashes as strings #15

Merged
merged 2 commits into from
Dec 29, 2024

Conversation

ektrah
Copy link
Contributor

@ektrah ektrah commented Dec 11, 2024

It can be a bit tricky to convert the password hash correctly between Span<byte> and string, so it might be helpful to provide overloads in the Argon2id class that do the conversion for the user.

The unsafe code can be replaced with Marshal.AllocHGlobal, Marshal.PtrToStringAnsi, and Marshal.FreeHGlobal in a try ... finally ... if preferred.

@samuel-lucas6
Copy link
Owner

This is a good idea. Thanks @ektrah! I'll try to take a look tomorrow if I get time.

Copy link
Owner

@samuel-lucas6 samuel-lucas6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I've taken a look. I'm happy to do these changes myself if you'd prefer. I don't really know what the etiquette is with PRs.

@@ -43,6 +57,14 @@ public static bool VerifyHash(ReadOnlySpan<byte> hash, ReadOnlySpan<byte> passwo
return crypto_pwhash_str_verify(hash, password, (ulong)password.Length) == 0;
}

public static bool VerifyHash(string hash, ReadOnlySpan<byte> password)
{
Validation.NotNull(nameof(hash), hash);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change this to Validation.NotNullOrEmpty().

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, it's probably better to do Validation.NotNull() and then Validation.SizeBetween() with the MinHashSize and MaxHashSize constants.

@@ -54,10 +76,29 @@ public static bool NeedsRehash(ReadOnlySpan<byte> hash, int iterations, int memo
return ret == -1 ? throw new FormatException("Invalid encoded password hash.") : ret == 1;
}

public static bool NeedsRehash(string hash, int iterations, int memorySize)
{
Validation.NotNull(nameof(hash), hash);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change this to Validation.NotNullOrEmpty().

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, it's probably better to do Validation.NotNull() and then Validation.SizeBetween() with the MinHashSize and MaxHashSize constants.

bool rehash = Argon2id.NeedsRehash(h, iterations, memorySize);
Assert.IsFalse(rehash);
}

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing ComputeHash_String_Invalid, not that there's much to test.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are also no NeedsRehash tests.

@samuel-lucas6
Copy link
Owner

Thank you for making changes. I'll try to review this next weekend.

Copy link
Owner

@samuel-lucas6 samuel-lucas6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll address the remaining comments.

@samuel-lucas6 samuel-lucas6 merged commit f8e583a into samuel-lucas6:main Dec 29, 2024
4 checks passed
@ektrah ektrah deleted the argon2id-convenience branch January 1, 2025 11:22
@ektrah
Copy link
Contributor Author

ektrah commented Jan 1, 2025

The PR etiquette depends. If someone really wants their code merged into your project, you can expect them to put in some effort to make sure the code style is followed, full unit tests are included, etc.

In this case, I just wanted to make a suggestion, but not without providing some sample code to show what I mean. It's up to you whether you like the suggestion or not, and if so, whether you want to build on the sample code or implement the suggestion in a different way, which of course means some effort on your part.

I'm glad you liked my suggestion. 😸 I would perhaps even deprecate the old overloads, since there isn't much saved when passing a buffer instead of a string and the API would be come simpler. I guess most API users will use the string overloads.

For VerifyHash, I'm not sure whether the method should throw an exception or return false if the hash is invalid. In general, a method should throw an exception when it is used incorrectly, and not when it is used correctly but has a negative result. If it is a wrong use of VerifyHash to pass an invalid hash, then it would be helpful to offer a method ValidateHash with which the caller of VerifyHash can check beforehand whether the hash is valid or not to avoid the exception.

@samuel-lucas6
Copy link
Owner

I'm glad you liked my suggestion. 😸 I would perhaps even deprecate the old overloads, since there isn't much saved when passing a buffer instead of a string and the API would be come simpler. I guess most API users will use the string overloads.

Yes, I might do that. There's probably not much use for them.

For VerifyHash, I'm not sure whether the method should throw an exception or return false if the hash is invalid. In general, a method should throw an exception when it is used incorrectly, and not when it is used correctly but has a negative result. If it is a wrong use of VerifyHash to pass an invalid hash, then it would be helpful to offer a method ValidateHash with which the caller of VerifyHash can check beforehand whether the hash is valid or not to avoid the exception.

This is an interesting point. However, I did it this way to prevent Argon2i hashes being verified since this library deliberately only supports Argon2id. As long as someone is using this library for computing the hashes, the method shouldn't throw.

samuel-lucas6 added a commit that referenced this pull request Jan 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants