technion / ruby-argon2

A Ruby gem offering bindings for Argon2 password hashing
MIT License
229 stars 30 forks source link

Make default costs RFC 9106's second preferred option; introduce named cost profiles #62

Closed f3ndot closed 1 year ago

f3ndot commented 1 year ago

RFC 9106 is the formal standard for describing Argon2. It also gives the official recommended cost parameters that should be sufficient for all environments. This PR introduces the concept of named profiles for a set of cost parameters/values and changes the default costs to :rfc_9106_low_memory, the second preferred option in the RFC. The RFC's first choice can be quite computationally expensive and, mirroring Python's argon2-cffi, we leave that as an opt-in choice.

A developer can use one of the named profiles, or continue to hand specify costs:

hasher = Argon2::Password.new(profile: :rfc_9106_high_memory)
hasher.create("password")
    => "$argon2id$v=19$m=2097152,t=1,p=4$LvHa74Yax7uCWPN7P6/oQQ$V1dMt4dfuYSmLpwUTpKUzg+RrXjWzWHlE6NLowBzsAg"

hasher = Argon2::Password.new(t_cost: 2, m_cost: 16, p_cost: 1)
hasher.create("password")
    => "$argon2i$v=19$m=65536,t=2,p=1$jL7lLEAjDN+pY2cG1N8D2g$iwj1ueduCvm6B9YVjBSnAHu+6mKzqGmDW745ALR38Uo"

The list of named cost profiles are:

A developer can see the list of profiles with Argon2::Profiles.to_a and the actual cost values with .to_h or [name]. As guidance changes over time (OWASP has its own recommended values), the list of profiles may expand or even change their values.

technion commented 1 year ago

@f3ndot Thanks for this PR. I like the code changes - if you wouldn't mind dealing with the Rubocop style issues I'll be happy to merge this.

f3ndot commented 1 year ago

@technion awesome, glad to hear it! Only one cop was a false-positive and was inline disabled accordingly.

f3ndot commented 1 year ago

I will quickly say that in https://github.com/OWASP/CheatSheetSeries/issues/1183 there is some disagreement about how "good" these RFC values are. It may be worth considering https://github.com/technion/ruby-argon2/issues/63 and then adding in the OWASP values before release. Frankly the lack of consensus makes is difficult to agree one what a sane default should be.

I wonder what the most common default is for most languages's implementation of argon2. As mentioned in the description, right now this PR mirrors Python's argon2-cffi default.

coveralls commented 1 year ago

Coverage Status

coverage: 99.342% (-0.7%) from 100.0% when pulling e81b812c0732fe06a570d82a0fc4bce74bfdaa32 on f3ndot:named-cost-profiles-default-rf9106 into e4e74b80f50113e39efe1fc36a645346356a43a1 on technion:master.

technion commented 1 year ago

I must concede my initial apprehension was simply down to the fact everyone has their own preference for defaults, I've had several offline discussions with people and basically came to the conclusion you'll never not having someone complaining it's wrong.

This profiles approach sounds reasonable because at least you referred to RFCs. Thanks for fixing linting, I'll merge this and will cut a release shortly so people can start using this. I tried to approve it last night and had a power outage instead.