Class: BCrypt::Engine
- Inherits:
-
Object
- Object
- BCrypt::Engine
- Defined in:
- lib/bcrypt.rb,
ext/mri/bcrypt_ext.c
Overview
A Ruby wrapper for the bcrypt() C extension calls and the Java calls.
Constant Summary collapse
- DEFAULT_COST =
The default computational expense parameter.
10
- MIN_COST =
The minimum cost supported by the algorithm.
4
- MAX_SALT_LENGTH =
Maximum possible size of bcrypt() salts.
16
Class Method Summary collapse
-
.__bc_crypt(key, setting) ⇒ Object
Given a secret and a salt, generates a salted hash (which you can then store safely).
-
.__bc_salt(prefix, count, input) ⇒ Object
Given a logarithmic cost parameter, generates a salt for use with
bc_crypt
. -
.autodetect_cost(salt) ⇒ Object
Autodetects the cost from the salt string.
-
.calibrate(upper_time_limit_in_ms) ⇒ Object
Returns the cost factor which will result in computation times less than
upper_time_limit_in_ms
. -
.generate_salt(cost = DEFAULT_COST) ⇒ Object
Generates a random salt with a given computational cost.
-
.hash_secret(secret, salt, cost = nil) ⇒ Object
Given a secret and a valid salt (see BCrypt::Engine.generate_salt) calculates a bcrypt() password hash.
-
.valid_salt?(salt) ⇒ Boolean
Returns true if
salt
is a valid bcrypt() salt, false if not. -
.valid_secret?(secret) ⇒ Boolean
Returns true if
secret
is a valid bcrypt() secret, false if not.
Class Method Details
.__bc_crypt(key, setting) ⇒ Object
Given a secret and a salt, generates a salted hash (which you can then store safely).
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'ext/mri/bcrypt_ext.c', line 54
static VALUE bc_crypt(VALUE self, VALUE key, VALUE setting) {
char * value;
void * data;
int size;
VALUE out;
data = NULL;
size = 0xDEADBEEF;
if(NIL_P(key) || NIL_P(setting)) return Qnil;
value = crypt_ra(
NIL_P(key) ? NULL : StringValuePtr(key),
NIL_P(setting) ? NULL : StringValuePtr(setting),
&data,
&size);
if(!value) return Qnil;
out = rb_str_new(data, size - 1);
xfree(data);
return out;
}
|
.__bc_salt(prefix, count, input) ⇒ Object
Given a logarithmic cost parameter, generates a salt for use with bc_crypt
.
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'ext/mri/bcrypt_ext.c', line 34
static VALUE bc_salt(VALUE self, VALUE prefix, VALUE count, VALUE input) {
char * salt;
VALUE str_salt;
salt = crypt_gensalt_ra(
StringValuePtr(prefix),
NUM2ULONG(count),
NIL_P(input) ? NULL : StringValuePtr(input),
NIL_P(input) ? 0 : RSTRING_LEN(input));
if(!salt) return Qnil;
str_salt = rb_str_new2(salt);
xfree(salt);
return str_salt;
}
|
.autodetect_cost(salt) ⇒ Object
Autodetects the cost from the salt string.
109 110 111 |
# File 'lib/bcrypt.rb', line 109 def self.autodetect_cost(salt) salt[4..5].to_i end |
.calibrate(upper_time_limit_in_ms) ⇒ Object
Returns the cost factor which will result in computation times less than upper_time_limit_in_ms
.
Example:
BCrypt.calibrate(200) #=> 10
BCrypt.calibrate(1000) #=> 12
# should take less than 200ms
BCrypt::Password.create("woo", :cost => 10)
# should take less than 1000ms
BCrypt::Password.create("woo", :cost => 12)
99 100 101 102 103 104 105 106 |
# File 'lib/bcrypt.rb', line 99 def self.calibrate(upper_time_limit_in_ms) 40.times do |i| start_time = Time.now Password.create("testing testing", :cost => i+1) end_time = Time.now - start_time return i if end_time * 1_000 > upper_time_limit_in_ms end end |
.generate_salt(cost = DEFAULT_COST) ⇒ Object
Generates a random salt with a given computational cost.
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/bcrypt.rb', line 60 def self.generate_salt(cost = DEFAULT_COST) cost = cost.to_i if cost > 0 if cost < MIN_COST cost = MIN_COST end if RUBY_PLATFORM == "java" Java.bcrypt_jruby.BCrypt.gensalt(cost) else prefix = "$2a$05$CCCCCCCCCCCCCCCCCCCCC.E5YPO9kmyuRGyh0XouQYb4YMJKvyOeW" __bc_salt(prefix, cost, OpenSSL::Random.random_bytes(MAX_SALT_LENGTH)) end else raise Errors::InvalidCost.new("cost must be numeric and > 0") end end |
.hash_secret(secret, salt, cost = nil) ⇒ Object
Given a secret and a valid salt (see BCrypt::Engine.generate_salt) calculates a bcrypt() password hash.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/bcrypt.rb', line 39 def self.hash_secret(secret, salt, cost = nil) if valid_secret?(secret) if valid_salt?(salt) if cost.nil? cost = autodetect_cost(salt) end if RUBY_PLATFORM == "java" Java.bcrypt_jruby.BCrypt.hashpw(secret.to_s, salt.to_s) else __bc_crypt(secret.to_s, salt) end else raise Errors::InvalidSalt.new("invalid salt") end else raise Errors::InvalidSecret.new("invalid secret") end end |
.valid_salt?(salt) ⇒ Boolean
Returns true if salt
is a valid bcrypt() salt, false if not.
78 79 80 |
# File 'lib/bcrypt.rb', line 78 def self.valid_salt?(salt) !!(salt =~ /^\$[0-9a-z]{2,}\$[0-9]{2,}\$[A-Za-z0-9\.\/]{22,}$/) end |
.valid_secret?(secret) ⇒ Boolean
Returns true if secret
is a valid bcrypt() secret, false if not.
83 84 85 |
# File 'lib/bcrypt.rb', line 83 def self.valid_secret?(secret) secret.respond_to?(:to_s) end |