22 Feb 2013, 18:20

Power

Share

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.