-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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
x/crypto/scrypt,x/crypto/argon2: add high-level APIs #16971
Comments
Seems reasonable to me, but @agl should take a look. |
Ping @agl. |
I just added some better documentation here, so hopefully this is better now.
I'd feel uncomfortable publishing this without having some sort of standard present on the scrypt website. You could ask Colin Percival if he is interested in it.
This would be reasonable but we'd need to figure out what the hash input should be.
The API for bcrypt takes a |
Thanks for taking a look at this @kevinburke (I'd forgotten myself)
Noted. I pinged Colin on Twitter, and as there isn't a specified output format (there isn't in the paper), have asked if there's any intent to specify. Unlikely, but doesn't hurt to ask. The other two points are somewhat held up on a standard format. The alternative would be to return a struct of the params for the caller to then stringify as needed. PS: I did note the improved params "for 2017" CL the other day, which is a good start. |
Ping @agl @FiloSottile |
Here's a proposal for a high-level password API for scrypt.
We should just fix r = 8 and p = 1, as there is no reason to change those, and users can still use the low-level Key interface. We can support different values in Check. For the We should probably not have minimum and maximum costs, but the Check docs should recommend checking with Cost if the hash is not trusted. Cost needs to take r and p into account, by scaling the returned cost relatively to them. While at it, let's also do argon2.
We've left out threads because it doesn't seem to be widely used (is that true?) and one can still use Key, but had to return it from Cost because it affects the performance in a way that is not as easily aggregated as scrypt.Cost. RecommendedMemory matches the memory of scrypt.RecommendedCost. -- @FiloSottile and @katiehockman |
This comment has been minimized.
This comment has been minimized.
Using very long names because they already exist is not typically a good pattern. Cleaning up the API is almost certainly worth doing. |
@FiloSottile posted a new API 19 days ago and there have not been many comments. Does anyone object to accepting this new API? |
After my initial comment, I have changed the stance on this. I think it might be worth adding support for actually changing parallelism. Otherwise I have nothing to object. I also thought of another thing. Wouldn’t it be useful to have the formatting functions exposed so people using the IDKey() and Key() functions could still encode and decode the standardized format for Argon2 hash storage? |
I’m in favor of @FiloSottile‘s API - I could nitpick, but I also appreciate there is no such thing as a perfect API:
The other comments w.r.t. these diverging from the bcrypt API are fair, but I agree with Russ that this is an opportunity to improve, with any new KDF following this new API as much as possible. |
FWIW, it's not just Check. There is a signature:
That seems pretty clear. |
I just want to elaborate more with what I propose as additions to the API suggested by @FiloSottile. My previous post was perhaps a bit too wage in my opinion, so I will try to make it a bit clearer.
These are my suggestions. I think this would be a great addition to the proposed API and I would appreciate seeing this part of the implementation. |
What happens if
One nice thing about the name |
Can you show some examples of parallelism being used in the wild for password hashing? I don't think it's worth adding that decision to the developer's plate.
Maybe, but I'm not sure how many people would need this, and there's always time to add APIs, none to remove them.
Not a strong opinion, but I feel like the argument names do that work, as Russ said, and
It always returns an error (unless someone intentionally makes a password in the format of a hash), so presumably never makes it to production.
For what use cases? This is one of those things we can pick for the developer and avoid friction and issues. Something important to keep in mind is that extra flexibility is not intrinsically good, because it comes at a price in complexity and user confusion. |
Agree with Filippo on simplicity - key length, output length especially.
Improperly handled password hashing has a huge blast radius. Keeping it as
opinionated as possible will only help reduce that.
(Folks who want to roll their own will roll their own - but let’s not make
it easier!)
|
While we're at it, I frequently have to interface with applications that rely on the SCRAM family of SASL mechanisms (which uses PBKDF2), or which use PBKDF2 directly for password hashing to take advantage of the various FIPS validated implementations. Because of this it would be nice to have a similar API for PBKDF2 (recommended iteration count taken from the OWASP cheat sheet) :
I left off a way to set the hash since the point of this API is to be simple and not give the user too many knobs. I suspect we'd just want to use SHA256, document it, and call it a day. |
Made a couple changes based on feedback from @rsc: added memory to argon2.Calibrate, and made the constants typed. We should have a check for memory to be realistic, so we can detect if MB and KB are being swapped, and should have an example of upgrading the cost.
I'd love to do PBKDF2 at the same time, but is there a crypt prefix for it? |
Take my use case as an example. I am producing a 64byte long hash and splitting it to have one half for AES encryption and one for storage. Perhaps having a setting but only allowing output of hashes longer than 32 bytes? I mean, one of the reasons for using My implementation is also the reason that I would prefer to have functions for decoding and encoding strings with parameters to avoid having to write my own parsing code, which feel wrong from a security standpoint.I could see other users having use of it as well. |
I think you are firmly in "use the |
@FiloSottile proposed a revised API in #16971 (comment) 11 days ago. Does anyone object to this API? Thanks. |
The proposal in #16971 sounds great to me. It would remove the need to use wrappers such as this one in applications. Two questions around the argon2 implementation:
|
@FiloSottile can you reply to @bojanz's comment right above this one? That clarification comment aside, it sounds like this is a likely accept. |
Sorry I had missed this.
Yes, there's consensus on using that for password hashes, so we can just choose for the user.
I think this is a sad mistake, because using literally all the available memory is not at all practical in multi-user shared environments like servers, and application developers don't have (nor should have) the information to assess the marginal value of more memory against hardware attackers. Lacking a recommendation from the authors, I think being consistent with scrypt so no one is surprised when (or dissuaded from) switching is best. |
No change in consensus, so accepted. |
@FiloSottile |
I would like to work on this. Just one thing to clarify from the original proposal:
The
And @kevinburke wrote:
Apparently the hash-storing universe lacks a standard in general. For this implementation I would encode it the same way as python's passlib implementation, which is consistent with PHC / argon2. At least to have some kind of portability.
|
Change https://go.dev/cl/431595 mentions this issue: |
Abandoned work on this issue, no responses in review. Implemented and using my own solution meanwhile. |
Summary: The x/crypto/scrypt package has a very simple API that puts the onus of figuring out salt generation and sensible N/r/p values on the package user. We should attempt to mirror the bcrypt packages' API and provide sensible defaults.
Details:
GenerateFromPassword
function that generates output in the formN$r$p$salt$dk
(noting that there is no 'standard' for scrypt here)CompareHashAndPassword
functionCost
function that can return the cost of a given output (i.e. for determining whether to upgrade or not)Note that I've done most of this work in https://godoc.org/github.com/elithrar/simple-scrypt and would seek to bring most of this in.
The text was updated successfully, but these errors were encountered: