Class: SCrypt::Password
- Inherits:
-
String
- Object
- String
- SCrypt::Password
- Defined in:
- lib/scrypt.rb
Overview
A password management class which allows you to safely store users’ passwords and compare them.
Example usage:
include "scrypt"
# hash a user's password
@password = Password.create("my grand secret")
@password #=> "2000$8$1$f5f2fa5fe5484a7091f1299768fbe92b5a7fbc77$6a385f22c54d92c314b71a4fd5ef33967c93d679"
# store it safely
@user.update_attribute(:password, @password)
# read it back
@user.reload!
@db_password = Password.new(@user.password)
# compare it after retrieval
@db_password == "my grand secret" #=> true
@db_password == "a paltry guess" #=> false
Instance Attribute Summary collapse
-
#cost ⇒ Object
readonly
The cost factor used to create the hash.
-
#digest ⇒ Object
readonly
The hash portion of the stored password hash.
-
#salt ⇒ Object
readonly
The salt of the store password hash.
Class Method Summary collapse
-
.create(secret, options = {}) ⇒ Object
Hashes a secret, returning a SCrypt::Password instance.
Instance Method Summary collapse
-
#==(secret) ⇒ Object
(also: #is_password?)
Compares a potential secret against the hash.
-
#initialize(raw_hash) ⇒ Password
constructor
Initializes a SCrypt::Password instance with the data from a stored hash.
Constructor Details
#initialize(raw_hash) ⇒ Password
Initializes a SCrypt::Password instance with the data from a stored hash.
239 240 241 242 243 244 245 246 |
# File 'lib/scrypt.rb', line 239 def initialize(raw_hash) if valid_hash?(raw_hash) self.replace(raw_hash) @cost, @salt, @digest = split_hash(self.to_s) else raise Errors::InvalidHash.new("invalid hash") end end |
Instance Attribute Details
#cost ⇒ Object (readonly)
The cost factor used to create the hash.
207 208 209 |
# File 'lib/scrypt.rb', line 207 def cost @cost end |
#digest ⇒ Object (readonly)
The hash portion of the stored password hash.
203 204 205 |
# File 'lib/scrypt.rb', line 203 def digest @digest end |
#salt ⇒ Object (readonly)
The salt of the store password hash
205 206 207 |
# File 'lib/scrypt.rb', line 205 def salt @salt end |
Class Method Details
.create(secret, options = {}) ⇒ Object
Hashes a secret, returning a SCrypt::Password instance. Takes five options (optional), which will determine the salt/key’s length and the cost limits of the computation. :key_len specifies the length in bytes of the key you want to generate. The default is 32 bytes (256 bits). Minimum is 16 bytes (128 bits). Maximum is 512 bytes (4096 bits). :salt_size specifies the size in bytes of the random salt you want to generate. The default and minimum is 8 bytes (64 bits). Maximum is 32 bytes (256 bits). :max_time specifies the maximum number of seconds the computation should take. :max_mem specifies the maximum number of bytes the computation should take. A value of 0 specifies no upper limit. The minimum is always 1 MB. :max_memfrac specifies the maximum memory in a fraction of available resources to use. Any value equal to 0 or greater than 0.5 will result in 0.5 being used. The scrypt key derivation function is designed to be far more secure against hardware brute-force attacks than alternative functions such as PBKDF2 or bcrypt. The designers of scrypt estimate that on modern (2009) hardware, if 5 seconds are spent computing a derived key, the cost of a hardware brute-force attack against scrypt is roughly 4000 times greater than the cost of a similar attack against bcrypt (to find the same password), and 20000 times greater than a similar attack against PBKDF2. Default options will result in calculation time of approx. 200 ms with 1 MB memory use.
Example:
@password = SCrypt::Password.create("my secret", :max_time => 0.25)
224 225 226 227 228 229 230 231 232 233 234 235 |
# File 'lib/scrypt.rb', line 224 def create(secret, = {}) = SCrypt::Engine::DEFAULTS.merge() #Clamp minimum/maximum keylen [:key_len] = 16 if [:key_len] < 16 [:key_len] = 512 if [:key_len] > 512 #Clamp minimum/maximum salt_size [:salt_size] = 8 if [:salt_size] < 8 [:salt_size] = 32 if [:salt_size] > 32 salt = SCrypt::Engine.generate_salt() hash = SCrypt::Engine.hash_secret(secret, salt, [:key_len]) Password.new(hash) end |
Instance Method Details
#==(secret) ⇒ Object Also known as: is_password?
Compares a potential secret against the hash. Returns true if the secret is the original secret, false otherwise.
249 250 251 |
# File 'lib/scrypt.rb', line 249 def ==(secret) SecurityUtils.secure_compare(self, SCrypt::Engine.hash_secret(secret, @cost + @salt, self.digest.length / 2)) end |