LoupVaillant / Monocypher

An easy to use, easy to deploy crypto library
https://monocypher.org
Other
614 stars 80 forks source link

Trouble understanding and using Monocypher #154

Closed aggsol closed 4 years ago

aggsol commented 4 years ago

I am trying to use Monocypher to hash user passwords. While I can read the manual front page all links to functions like crypto_blake2b() of crypto_blake2b_final() are not working. I can of course read the header and see how e. g. the Blake2 functions should be called.

But even then it s not clear to me how to add the salt to the hash. Do I hash the salt first or last? Should I append or prepend the salt to the password? How can I hash with multiple rounds?

In the current state I don't feel that I am using the library correctly. I fear I do some stupid error and the security is broken already. Better documentation or examples would provide confidence for non-crypto programmers that need to use it.

fscoto commented 4 years ago

While I can read the manual front page all links to functions like crypto_blake2b() of crypto_blake2b_final() are not working.

Oh dear. That's an issue caused by Loup's workflow for the web manual and probably needs urgent fixing if you're running into this as an issue. As a workaround, you can use:


But even then it s not clear to me how to add the salt to the hash. Do I hash the salt first or last? Should I append or prepend the salt to the password? How can I hash with multiple rounds?

None of these, actually. BLAKE2b is a general-purpose cryptographic hash. You're not supposed to sue the crypto_blake2b_* family of functions for password hashing at all. Password hashing should use a specialized, computation-intensive hashing function to delay attackers from churning through a lot of hashes very quickly (which is, I presume, why you asked about multiple rounds).

You're looking for "password key derivation", i.e. the crypto_argon2i() functions. Password hashing and password key derivation happen to have the same requirements; in the case of password hashing for storing passwords, you store the derived key (== the password hash) as such instead of using it for encryption operations. Perhaps that should've been stated more clearly in the intro page.

I hope that helps; if you have any follow-up questions, feel free to ask.

aggsol commented 4 years ago

@fscoto It was not clear to me that password hashing for storage and password key derivation are the same kind of problem/work. Your web man pages are great read and navigate, thank you. The official web manual needs to be fixed asap then.

LoupVaillant commented 4 years ago

Hi @aggsol,

I'll fix the web pages shortly. I didn't think it would be such a problem though, sorry about that.

It was not clear to me that password hashing for storage and password key derivation are the same kind of problem/work.

Different problems, same solution. When you store a password hash, you just want to compare hashes, while password key derivation is (usually) used to encrypt & decrypt stuff. In both case though, you just need the hash to be unpredictable, so you end up using the same primitive (Argon2i here).

@fscoto Perhaps we should add an explicit mention in the Blake2b manual that password hashing and password key derivation should use Argon2i instead? Perhaps a quick mention in the initial description, then a more fleshed out version under "Security considerations"? I also expect we'd need the same kind of work for SHA-512.

aggsol commented 4 years ago

I'll fix the web pages shortly. I didn't think it would be such a problem though, sorry about that.

I usually read the the web documentation or web manpages in the browser while coding. I guess I am not the only one working this way. So good web based documentation is key. I am no crypto expert and so are most developers tasked to implement crypto functions into something. If you target that audience then easy access to documentation and example would be important.

Different problems, same solution. When you store a password hash, you just want to compare hashes, while password key derivation is (usually) used to encrypt & decrypt stuff. In both case though, you just need the hash to be unpredictable, so you end up using the same primitive (Argon2i here).

Thank you for the clarification.

LoupVaillant commented 4 years ago

The links in the manual on the web site should be fixed now. Closing the bug, thanks again for the report.

And don't hesitate to re-open it if you find a dead or misdirected link. I've been pretty thorough, but a mistake is still possible (the script I've written has 60 redirections, and I'm not exactly foolproof).