bcrypt-ruby 2.0.2 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of bcrypt-ruby might be problematic. Click here for more details.
- data/CHANGELOG +6 -1
- data/README +14 -0
- data/Rakefile +4 -4
- data/lib/bcrypt.rb +8 -8
- data/spec/bcrypt/engine_spec.rb +6 -6
- metadata +49 -42
data/CHANGELOG
CHANGED
@@ -13,4 +13,9 @@
|
|
13
13
|
|
14
14
|
2.0.2 Jun 06 2007
|
15
15
|
- Fixed example code in the README [Winson]
|
16
|
-
- Fixed Solaris compatibility [Jeremy LaTrasse, Twitter crew]
|
16
|
+
- Fixed Solaris compatibility [Jeremy LaTrasse, Twitter crew]
|
17
|
+
|
18
|
+
2.0.3 May 07 2008
|
19
|
+
- Made exception classes descend from StandardError, not Exception [Dan42]
|
20
|
+
- Changed BCrypt::Engine.hash to BCrypt::Engine.hash_secret to avoid Merb
|
21
|
+
sorting issues. [Lee Pope]
|
data/README
CHANGED
@@ -91,6 +91,8 @@ Check the rdocs for more details -- BCrypt, BCrypt::Password.
|
|
91
91
|
|
92
92
|
bcrypt() is a hashing algorithm designed by Niels Provos and David Mazières of the OpenBSD Project.
|
93
93
|
|
94
|
+
=== Background
|
95
|
+
|
94
96
|
Hash algorithms take a chunk of data (e.g., your user's password) and create a "digital fingerprint," or hash, of it.
|
95
97
|
Because this process is not reversible, there's no way to go from the hash back to the password.
|
96
98
|
|
@@ -102,11 +104,15 @@ You can store the hash and check it against a hash made of a potentially valid p
|
|
102
104
|
|
103
105
|
<unique gibberish> =? hash(just_entered_password)
|
104
106
|
|
107
|
+
=== Rainbow Tables
|
108
|
+
|
105
109
|
But even this has weaknesses -- attackers can just run lists of possible passwords through the same algorithm, store the
|
106
110
|
results in a big database, and then look up the passwords by their hash:
|
107
111
|
|
108
112
|
PrecomputedPassword.find_by_hash(<unique gibberish>).password #=> "secret1"
|
109
113
|
|
114
|
+
=== Salts
|
115
|
+
|
110
116
|
The solution to this is to add a small chunk of random data -- called a salt -- to the password before it's hashed:
|
111
117
|
|
112
118
|
hash(salt + p) #=> <really unique gibberish>
|
@@ -137,9 +143,17 @@ fingerprints as quickly as possible. bcrypt(), though, is designed to be computa
|
|
137
143
|
If an attacker was using Ruby to check each password, they could check ~140,000 passwords a second with MD5 but only
|
138
144
|
~450 passwords a second with bcrypt().
|
139
145
|
|
146
|
+
=== Cost Factors
|
147
|
+
|
140
148
|
In addition, bcrypt() allows you to increase the amount of work required to hash a password as computers get faster. Old
|
141
149
|
passwords will still work fine, but new passwords can keep up with the times.
|
142
150
|
|
151
|
+
The default cost factor used by bcrypt-ruby is 10, which is fine for session-based authentication. If you are using a
|
152
|
+
stateless authentication architecture (e.g., HTTP Basic Auth), you will want to lower the cost factor to reduce your
|
153
|
+
server load and keep your request times down. This will lower the security provided you, but there are few alternatives.
|
154
|
+
|
155
|
+
== More Information
|
156
|
+
|
143
157
|
bcrypt() is currently used as the default password storage hash in OpenBSD, widely regarded as the most secure operating
|
144
158
|
system available.
|
145
159
|
|
data/Rakefile
CHANGED
@@ -7,7 +7,7 @@ require 'rake/rdoctask'
|
|
7
7
|
require "benchmark"
|
8
8
|
|
9
9
|
PKG_NAME = "bcrypt-ruby"
|
10
|
-
PKG_VERSION = "2.0.
|
10
|
+
PKG_VERSION = "2.0.3"
|
11
11
|
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
12
12
|
PKG_FILES = FileList[
|
13
13
|
'[A-Z]*',
|
@@ -26,7 +26,7 @@ CLOBBER.include(
|
|
26
26
|
"doc/coverage"
|
27
27
|
)
|
28
28
|
|
29
|
-
task :default => [:spec]
|
29
|
+
task :default => [:compile, :spec]
|
30
30
|
|
31
31
|
desc "Run all specs"
|
32
32
|
Spec::Rake::SpecTask.new do |t|
|
@@ -72,8 +72,7 @@ spec = Gem::Specification.new do |s|
|
|
72
72
|
|
73
73
|
s.extensions = FileList["ext/extconf.rb"].to_a
|
74
74
|
|
75
|
-
s.
|
76
|
-
s.author = ["Coda Hale"]
|
75
|
+
s.authors = ["Coda Hale"]
|
77
76
|
s.email = "coda.hale@gmail.com"
|
78
77
|
s.homepage = "http://bcrypt-ruby.rubyforge.org"
|
79
78
|
s.rubyforge_project = "bcrypt-ruby"
|
@@ -89,6 +88,7 @@ task :compile => [:clean] do
|
|
89
88
|
Dir.chdir('./ext')
|
90
89
|
system "ruby extconf.rb"
|
91
90
|
system "make"
|
91
|
+
Dir.chdir('..')
|
92
92
|
end
|
93
93
|
|
94
94
|
desc "Run a set of benchmarks on the compiled extension."
|
data/lib/bcrypt.rb
CHANGED
@@ -8,10 +8,10 @@ require "openssl"
|
|
8
8
|
# hashing passwords.
|
9
9
|
module BCrypt
|
10
10
|
module Errors
|
11
|
-
class InvalidSalt <
|
12
|
-
class InvalidHash <
|
13
|
-
class InvalidCost <
|
14
|
-
class InvalidSecret <
|
11
|
+
class InvalidSalt < StandardError; end # The salt parameter provided to bcrypt() is invalid.
|
12
|
+
class InvalidHash < StandardError; end # The hash parameter provided to bcrypt() is invalid.
|
13
|
+
class InvalidCost < StandardError; end # The cost parameter provided to bcrypt() is invalid.
|
14
|
+
class InvalidSecret < StandardError; end # The secret parameter provided to bcrypt() is invalid.
|
15
15
|
end
|
16
16
|
|
17
17
|
# A Ruby wrapper for the bcrypt() extension calls.
|
@@ -28,7 +28,7 @@ module BCrypt
|
|
28
28
|
|
29
29
|
# Given a secret and a valid salt (see BCrypt::Engine.generate_salt) calculates
|
30
30
|
# a bcrypt() password hash.
|
31
|
-
def self.
|
31
|
+
def self.hash_secret(secret, salt)
|
32
32
|
if valid_secret?(secret)
|
33
33
|
if valid_salt?(salt)
|
34
34
|
__bc_crypt(secret.to_s, salt)
|
@@ -123,7 +123,7 @@ module BCrypt
|
|
123
123
|
#
|
124
124
|
# @password = BCrypt::Password.create("my secret", :cost => 13)
|
125
125
|
def create(secret, options = { :cost => BCrypt::Engine::DEFAULT_COST })
|
126
|
-
Password.new(BCrypt::Engine.
|
126
|
+
Password.new(BCrypt::Engine.hash_secret(secret, BCrypt::Engine.generate_salt(options[:cost])))
|
127
127
|
end
|
128
128
|
end
|
129
129
|
|
@@ -139,7 +139,7 @@ module BCrypt
|
|
139
139
|
|
140
140
|
# Compares a potential secret against the hash. Returns true if the secret is the original secret, false otherwise.
|
141
141
|
def ==(secret)
|
142
|
-
super(BCrypt::Engine.
|
142
|
+
super(BCrypt::Engine.hash_secret(secret, @salt))
|
143
143
|
end
|
144
144
|
alias_method :is_password?, :==
|
145
145
|
|
@@ -158,4 +158,4 @@ module BCrypt
|
|
158
158
|
return v, c.to_i, h[0, 29], mash[-31, 31]
|
159
159
|
end
|
160
160
|
end
|
161
|
-
end
|
161
|
+
end
|
data/spec/bcrypt/engine_spec.rb
CHANGED
@@ -35,16 +35,16 @@ context "Generating BCrypt hashes" do
|
|
35
35
|
end
|
36
36
|
|
37
37
|
specify "should produce a string" do
|
38
|
-
BCrypt::Engine.
|
38
|
+
BCrypt::Engine.hash_secret(@password, @salt).should be_an_instance_of(String)
|
39
39
|
end
|
40
40
|
|
41
41
|
specify "should raise an InvalidSalt error if the salt is invalid" do
|
42
|
-
lambda { BCrypt::Engine.
|
42
|
+
lambda { BCrypt::Engine.hash_secret(@password, 'nino') }.should raise_error(BCrypt::Errors::InvalidSalt)
|
43
43
|
end
|
44
44
|
|
45
45
|
specify "should raise an InvalidSecret error if the secret is invalid" do
|
46
|
-
lambda { BCrypt::Engine.
|
47
|
-
lambda { BCrypt::Engine.
|
46
|
+
lambda { BCrypt::Engine.hash_secret(nil, @salt) }.should_not raise_error(BCrypt::Errors::InvalidSecret)
|
47
|
+
lambda { BCrypt::Engine.hash_secret(false, @salt) }.should_not raise_error(BCrypt::Errors::InvalidSecret)
|
48
48
|
end
|
49
49
|
|
50
50
|
specify "should be interoperable with other implementations" do
|
@@ -57,7 +57,7 @@ context "Generating BCrypt hashes" do
|
|
57
57
|
["0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", "$2a$05$abcdefghijklmnopqrstuu", "$2a$05$abcdefghijklmnopqrstuu5s2v8.iXieOjg/.AySBTTZIIVFJeBui"]
|
58
58
|
]
|
59
59
|
for secret, salt, test_vector in test_vectors
|
60
|
-
BCrypt::Engine.
|
60
|
+
BCrypt::Engine.hash_secret(secret, salt).should eql(test_vector)
|
61
61
|
end
|
62
62
|
end
|
63
|
-
end
|
63
|
+
end
|
metadata
CHANGED
@@ -1,49 +1,46 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.2
|
3
|
-
specification_version: 1
|
4
2
|
name: bcrypt-ruby
|
5
3
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 2.0.
|
7
|
-
date: 2007-06-07 00:00:00 -07:00
|
8
|
-
summary: OpenBSD's bcrypt() password hashing algorithm.
|
9
|
-
require_paths:
|
10
|
-
- lib
|
11
|
-
email: coda.hale@gmail.com
|
12
|
-
homepage: http://bcrypt-ruby.rubyforge.org
|
13
|
-
rubyforge_project: bcrypt-ruby
|
14
|
-
description: bcrypt() is a sophisticated and secure hash algorithm designed by The OpenBSD project for hashing passwords. bcrypt-ruby provides a simple, humane wrapper for safely handling passwords.
|
15
|
-
autorequire: bcrypt
|
16
|
-
default_executable:
|
17
|
-
bindir: bin
|
18
|
-
has_rdoc: true
|
19
|
-
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
-
requirements:
|
21
|
-
- - ">"
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: 0.0.0
|
24
|
-
version:
|
4
|
+
version: 2.0.3
|
25
5
|
platform: ruby
|
26
|
-
signing_key:
|
27
|
-
cert_chain:
|
28
|
-
post_install_message:
|
29
6
|
authors:
|
30
|
-
-
|
31
|
-
|
32
|
-
|
7
|
+
- Coda Hale
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-05-07 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: bcrypt() is a sophisticated and secure hash algorithm designed by The OpenBSD project for hashing passwords. bcrypt-ruby provides a simple, humane wrapper for safely handling passwords.
|
17
|
+
email: coda.hale@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions:
|
21
|
+
- ext/extconf.rb
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README
|
33
24
|
- COPYING
|
25
|
+
- CHANGELOG
|
26
|
+
- lib/bcrypt.rb
|
27
|
+
files:
|
34
28
|
- Rakefile
|
29
|
+
- COPYING
|
35
30
|
- README
|
31
|
+
- CHANGELOG
|
36
32
|
- lib/bcrypt.rb
|
37
|
-
- spec/bcrypt/engine_spec.rb
|
38
|
-
- spec/bcrypt/password_spec.rb
|
39
33
|
- spec/spec_helper.rb
|
34
|
+
- spec/bcrypt/password_spec.rb
|
35
|
+
- spec/bcrypt/engine_spec.rb
|
36
|
+
- ext/blowfish.c
|
40
37
|
- ext/bcrypt.c
|
41
38
|
- ext/bcrypt_ext.c
|
42
|
-
- ext/blowfish.c
|
43
39
|
- ext/blf.h
|
44
40
|
- ext/extconf.rb
|
45
|
-
|
46
|
-
|
41
|
+
has_rdoc: true
|
42
|
+
homepage: http://bcrypt-ruby.rubyforge.org
|
43
|
+
post_install_message:
|
47
44
|
rdoc_options:
|
48
45
|
- --title
|
49
46
|
- bcrypt-ruby
|
@@ -51,16 +48,26 @@ rdoc_options:
|
|
51
48
|
- --inline-source
|
52
49
|
- --main
|
53
50
|
- README
|
54
|
-
|
55
|
-
-
|
56
|
-
|
57
|
-
|
58
|
-
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
version:
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: "0"
|
64
|
+
version:
|
63
65
|
requirements: []
|
64
66
|
|
65
|
-
|
67
|
+
rubyforge_project: bcrypt-ruby
|
68
|
+
rubygems_version: 1.1.1
|
69
|
+
signing_key:
|
70
|
+
specification_version: 2
|
71
|
+
summary: OpenBSD's bcrypt() password hashing algorithm.
|
72
|
+
test_files: []
|
66
73
|
|