Finished a user athentication system today using BCrypt::Password.
There was an Aha! moment when I realized that they’ve defined the ==
operator to return true when the password matches, not when the strings are equal (as a novice like me might expect).
1.9.3p385 :002 > secret = BCrypt::Password.create("password")
=> "$2a$10$50UZDPv124TYHe4xwQLoBeuryd0lzcCkjVdepHQD41K9svNE7lXGe"
The hashed secret is saved in the database. It’s later retrieved and checked against the user input using ==
.
1.9.3p385 :005 > secret
=> "$2a$10$50UZDPv124TYHe4xwQLoBeuryd0lzcCkjVdepHQD41K9svNE7lXGe"
1.9.3p385 :006 > q = BCrypt::Password.new(secret)
=> "$2a$10$50UZDPv124TYHe4xwQLoBeuryd0lzcCkjVdepHQD41K9svNE7lXGe"
1.9.3p385 :007 > q == "password"
=> true
This also has the interesting side effect that ==
is not commutative.
1.9.3p385 :008 > "password" == q
=> false
My junior high math teacher would be disturbed by this. Such is the power of Ruby.