technion / ruby-argon2

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

Argon2::Password.create giving inconsistent results. #23

Closed jisaacks closed 6 years ago

jisaacks commented 6 years ago

When just using Argon2::Password.create I am starting to get different results every time (I have been using this code for over a year tho and it has not been an issue until now).

irb(main):037:0>  Argon2::Password.create('test')
=> "$argon2i$v=19$m=65536,t=2,p=1$3ErJO2+rrc15wMqyZo5lCw$SvhWCpzZXLkm2fHjbu/hvinYDgBpLotgwqovfVsxteA"
irb(main):038:0>  Argon2::Password.create('test')
=> "$argon2i$v=19$m=65536,t=2,p=1$42WXmH1kA6jb3dyVF/yIDg$Jv49rs8vi8TwIpUDp70ix92/aVguMyd2UGZW4+0TJYE"
irb(main):039:0>  Argon2::Password.create('test')
=> "$argon2i$v=19$m=65536,t=2,p=1$wgmydmPv6fsfxoP+lsA6Ag$06h1Jj5ArylVg6MaimCPpqjv0WPMx8/MQpgW1xImClQ"

however if I create an instance like this it works:

irb(main):063:0> hasher = Argon2::Password.new(t_cost: 2, m_cost: 16)
=> #<Argon2::Password:0x0055a8f4a1c190 @t_cost=2, @m_cost=16, @salt="?\xD6,q\xAB\a\x18}\x83\xFB\t\xB9\x81\x86F\xD5", @secret=nil>
irb(main):064:0> hasher.create("test") == hasher.create("test")
=> true

Could this be something environmental that is causing it to always be different? Is this a bug?

Happy to give any other info you may need.

technion commented 6 years ago

The value for the salt is generated randomly when you call "create" as a part of the initialisation:

https://github.com/technion/ruby-argon2/blob/master/lib/argon2.rb#L17

It is intended that you get different results for every hash you create (even with the same input), as this is how the salt prevents rainbow attacks.

This is consistent with the operation of bcrypt, and you can read more about this pattern here: https://stackoverflow.com/questions/39197989/laravel-5-using-bcrypt-on-same-string-gives-different-values

If would only be a bug if those inputs failed to verify, which is checked in the tests here: https://github.com/technion/ruby-argon2/blob/master/test/rubycheck_test.rb

In your second example, you've reused the hash object, which reuses the salt. This is probably a bad idea, and I'll add some documentation to this effect.

jisaacks commented 6 years ago

Thanks so much! That clarified everything.