bcrypt-ruby 3.1.2-x64-mingw32 → 3.1.3-x64-mingw32
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.
- checksums.yaml +7 -0
- data/CHANGELOG +4 -0
- data/README.md +6 -7
- data/lib/2.0/bcrypt_ext.so +0 -0
- data/lib/bcrypt.rb +6 -19
- metadata +51 -87
- data/.gitignore +0 -10
- data/.rspec +0 -3
- data/.travis.yml +0 -11
- data/Gemfile +0 -2
- data/Gemfile.lock +0 -35
- data/Rakefile +0 -74
- data/bcrypt-ruby.gemspec +0 -30
- data/ext/jruby/bcrypt_jruby/BCrypt.java +0 -752
- data/ext/mri/bcrypt_ext.c +0 -64
- data/ext/mri/crypt.c +0 -57
- data/ext/mri/crypt.h +0 -13
- data/ext/mri/crypt_blowfish.c +0 -786
- data/ext/mri/crypt_gensalt.c +0 -111
- data/ext/mri/ow-crypt.h +0 -35
- data/ext/mri/wrapper.c +0 -262
- data/lib/bcrypt/engine.rb +0 -120
- data/lib/bcrypt/error.rb +0 -22
- data/lib/bcrypt/password.rb +0 -87
- data/spec/TestBCrypt.java +0 -194
- data/spec/bcrypt/engine_spec.rb +0 -82
- data/spec/bcrypt/error_spec.rb +0 -37
- data/spec/bcrypt/password_spec.rb +0 -123
- data/spec/spec_helper.rb +0 -2
data/lib/bcrypt/error.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
module BCrypt
|
2
|
-
|
3
|
-
class Error < StandardError # :nodoc:
|
4
|
-
end
|
5
|
-
|
6
|
-
module Errors # :nodoc:
|
7
|
-
|
8
|
-
# The salt parameter provided to bcrypt() is invalid.
|
9
|
-
class InvalidSalt < BCrypt::Error; end
|
10
|
-
|
11
|
-
# The hash parameter provided to bcrypt() is invalid.
|
12
|
-
class InvalidHash < BCrypt::Error; end
|
13
|
-
|
14
|
-
# The cost parameter provided to bcrypt() is invalid.
|
15
|
-
class InvalidCost < BCrypt::Error; end
|
16
|
-
|
17
|
-
# The secret parameter provided to bcrypt() is invalid.
|
18
|
-
class InvalidSecret < BCrypt::Error; end
|
19
|
-
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
data/lib/bcrypt/password.rb
DELETED
@@ -1,87 +0,0 @@
|
|
1
|
-
module BCrypt
|
2
|
-
# A password management class which allows you to safely store users' passwords and compare them.
|
3
|
-
#
|
4
|
-
# Example usage:
|
5
|
-
#
|
6
|
-
# include BCrypt
|
7
|
-
#
|
8
|
-
# # hash a user's password
|
9
|
-
# @password = Password.create("my grand secret")
|
10
|
-
# @password #=> "$2a$10$GtKs1Kbsig8ULHZzO1h2TetZfhO4Fmlxphp8bVKnUlZCBYYClPohG"
|
11
|
-
#
|
12
|
-
# # store it safely
|
13
|
-
# @user.update_attribute(:password, @password)
|
14
|
-
#
|
15
|
-
# # read it back
|
16
|
-
# @user.reload!
|
17
|
-
# @db_password = Password.new(@user.password)
|
18
|
-
#
|
19
|
-
# # compare it after retrieval
|
20
|
-
# @db_password == "my grand secret" #=> true
|
21
|
-
# @db_password == "a paltry guess" #=> false
|
22
|
-
#
|
23
|
-
class Password < String
|
24
|
-
# The hash portion of the stored password hash.
|
25
|
-
attr_reader :checksum
|
26
|
-
# The salt of the store password hash (including version and cost).
|
27
|
-
attr_reader :salt
|
28
|
-
# The version of the bcrypt() algorithm used to create the hash.
|
29
|
-
attr_reader :version
|
30
|
-
# The cost factor used to create the hash.
|
31
|
-
attr_reader :cost
|
32
|
-
|
33
|
-
class << self
|
34
|
-
# Hashes a secret, returning a BCrypt::Password instance. Takes an optional <tt>:cost</tt> option, which is a
|
35
|
-
# logarithmic variable which determines how computational expensive the hash is to calculate (a <tt>:cost</tt> of
|
36
|
-
# 4 is twice as much work as a <tt>:cost</tt> of 3). The higher the <tt>:cost</tt> the harder it becomes for
|
37
|
-
# attackers to try to guess passwords (even if a copy of your database is stolen), but the slower it is to check
|
38
|
-
# users' passwords.
|
39
|
-
#
|
40
|
-
# Example:
|
41
|
-
#
|
42
|
-
# @password = BCrypt::Password.create("my secret", :cost => 13)
|
43
|
-
def create(secret, options = {})
|
44
|
-
cost = options[:cost] || BCrypt::Engine.cost
|
45
|
-
raise ArgumentError if cost > 31
|
46
|
-
Password.new(BCrypt::Engine.hash_secret(secret, BCrypt::Engine.generate_salt(cost), cost))
|
47
|
-
end
|
48
|
-
|
49
|
-
def valid_hash?(h)
|
50
|
-
h =~ /^\$[0-9a-z]{2}\$[0-9]{2}\$[A-Za-z0-9\.\/]{53}$/
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
# Initializes a BCrypt::Password instance with the data from a stored hash.
|
55
|
-
def initialize(raw_hash)
|
56
|
-
if valid_hash?(raw_hash)
|
57
|
-
self.replace(raw_hash)
|
58
|
-
@version, @cost, @salt, @checksum = split_hash(self)
|
59
|
-
else
|
60
|
-
raise Errors::InvalidHash.new("invalid hash")
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
# Compares a potential secret against the hash. Returns true if the secret is the original secret, false otherwise.
|
65
|
-
def ==(secret)
|
66
|
-
super(BCrypt::Engine.hash_secret(secret, @salt))
|
67
|
-
end
|
68
|
-
alias_method :is_password?, :==
|
69
|
-
|
70
|
-
private
|
71
|
-
|
72
|
-
# Returns true if +h+ is a valid hash.
|
73
|
-
def valid_hash?(h)
|
74
|
-
self.class.valid_hash?(h)
|
75
|
-
end
|
76
|
-
|
77
|
-
# call-seq:
|
78
|
-
# split_hash(raw_hash) -> version, cost, salt, hash
|
79
|
-
#
|
80
|
-
# Splits +h+ into version, cost, salt, and hash and returns them in that order.
|
81
|
-
def split_hash(h)
|
82
|
-
_, v, c, mash = h.split('$')
|
83
|
-
return v, c.to_i, h[0, 29].to_str, mash[-31, 31].to_str
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
end
|
data/spec/TestBCrypt.java
DELETED
@@ -1,194 +0,0 @@
|
|
1
|
-
// Copyright (c) 2006 Damien Miller <djm@mindrot.org>
|
2
|
-
//
|
3
|
-
// Permission to use, copy, modify, and distribute this software for any
|
4
|
-
// purpose with or without fee is hereby granted, provided that the above
|
5
|
-
// copyright notice and this permission notice appear in all copies.
|
6
|
-
//
|
7
|
-
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
8
|
-
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
9
|
-
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
10
|
-
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
11
|
-
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
12
|
-
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
13
|
-
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
14
|
-
|
15
|
-
import junit.framework.TestCase;
|
16
|
-
|
17
|
-
/**
|
18
|
-
* JUnit unit tests for BCrypt routines
|
19
|
-
* @author Damien Miller
|
20
|
-
* @version 0.2
|
21
|
-
*/
|
22
|
-
public class TestBCrypt extends TestCase {
|
23
|
-
String test_vectors[][] = {
|
24
|
-
{ "",
|
25
|
-
"$2a$06$DCq7YPn5Rq63x1Lad4cll.",
|
26
|
-
"$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s." },
|
27
|
-
{ "",
|
28
|
-
"$2a$08$HqWuK6/Ng6sg9gQzbLrgb.",
|
29
|
-
"$2a$08$HqWuK6/Ng6sg9gQzbLrgb.Tl.ZHfXLhvt/SgVyWhQqgqcZ7ZuUtye" },
|
30
|
-
{ "",
|
31
|
-
"$2a$10$k1wbIrmNyFAPwPVPSVa/ze",
|
32
|
-
"$2a$10$k1wbIrmNyFAPwPVPSVa/zecw2BCEnBwVS2GbrmgzxFUOqW9dk4TCW" },
|
33
|
-
{ "",
|
34
|
-
"$2a$12$k42ZFHFWqBp3vWli.nIn8u",
|
35
|
-
"$2a$12$k42ZFHFWqBp3vWli.nIn8uYyIkbvYRvodzbfbK18SSsY.CsIQPlxO" },
|
36
|
-
{ "a",
|
37
|
-
"$2a$06$m0CrhHm10qJ3lXRY.5zDGO",
|
38
|
-
"$2a$06$m0CrhHm10qJ3lXRY.5zDGO3rS2KdeeWLuGmsfGlMfOxih58VYVfxe" },
|
39
|
-
{ "a",
|
40
|
-
"$2a$08$cfcvVd2aQ8CMvoMpP2EBfe",
|
41
|
-
"$2a$08$cfcvVd2aQ8CMvoMpP2EBfeodLEkkFJ9umNEfPD18.hUF62qqlC/V." },
|
42
|
-
{ "a",
|
43
|
-
"$2a$10$k87L/MF28Q673VKh8/cPi.",
|
44
|
-
"$2a$10$k87L/MF28Q673VKh8/cPi.SUl7MU/rWuSiIDDFayrKk/1tBsSQu4u" },
|
45
|
-
{ "a",
|
46
|
-
"$2a$12$8NJH3LsPrANStV6XtBakCe",
|
47
|
-
"$2a$12$8NJH3LsPrANStV6XtBakCez0cKHXVxmvxIlcz785vxAIZrihHZpeS" },
|
48
|
-
{ "abc",
|
49
|
-
"$2a$06$If6bvum7DFjUnE9p2uDeDu",
|
50
|
-
"$2a$06$If6bvum7DFjUnE9p2uDeDu0YHzrHM6tf.iqN8.yx.jNN1ILEf7h0i" },
|
51
|
-
{ "abc",
|
52
|
-
"$2a$08$Ro0CUfOqk6cXEKf3dyaM7O",
|
53
|
-
"$2a$08$Ro0CUfOqk6cXEKf3dyaM7OhSCvnwM9s4wIX9JeLapehKK5YdLxKcm" },
|
54
|
-
{ "abc",
|
55
|
-
"$2a$10$WvvTPHKwdBJ3uk0Z37EMR.",
|
56
|
-
"$2a$10$WvvTPHKwdBJ3uk0Z37EMR.hLA2W6N9AEBhEgrAOljy2Ae5MtaSIUi" },
|
57
|
-
{ "abc",
|
58
|
-
"$2a$12$EXRkfkdmXn2gzds2SSitu.",
|
59
|
-
"$2a$12$EXRkfkdmXn2gzds2SSitu.MW9.gAVqa9eLS1//RYtYCmB1eLHg.9q" },
|
60
|
-
{ "abcdefghijklmnopqrstuvwxyz",
|
61
|
-
"$2a$06$.rCVZVOThsIa97pEDOxvGu",
|
62
|
-
"$2a$06$.rCVZVOThsIa97pEDOxvGuRRgzG64bvtJ0938xuqzv18d3ZpQhstC" },
|
63
|
-
{ "abcdefghijklmnopqrstuvwxyz",
|
64
|
-
"$2a$08$aTsUwsyowQuzRrDqFflhge",
|
65
|
-
"$2a$08$aTsUwsyowQuzRrDqFflhgekJ8d9/7Z3GV3UcgvzQW3J5zMyrTvlz." },
|
66
|
-
{ "abcdefghijklmnopqrstuvwxyz",
|
67
|
-
"$2a$10$fVH8e28OQRj9tqiDXs1e1u",
|
68
|
-
"$2a$10$fVH8e28OQRj9tqiDXs1e1uxpsjN0c7II7YPKXua2NAKYvM6iQk7dq" },
|
69
|
-
{ "abcdefghijklmnopqrstuvwxyz",
|
70
|
-
"$2a$12$D4G5f18o7aMMfwasBL7Gpu",
|
71
|
-
"$2a$12$D4G5f18o7aMMfwasBL7GpuQWuP3pkrZrOAnqP.bmezbMng.QwJ/pG" },
|
72
|
-
{ "~!@#$%^&*() ~!@#$%^&*()PNBFRD",
|
73
|
-
"$2a$06$fPIsBO8qRqkjj273rfaOI.",
|
74
|
-
"$2a$06$fPIsBO8qRqkjj273rfaOI.HtSV9jLDpTbZn782DC6/t7qT67P6FfO" },
|
75
|
-
{ "~!@#$%^&*() ~!@#$%^&*()PNBFRD",
|
76
|
-
"$2a$08$Eq2r4G/76Wv39MzSX262hu",
|
77
|
-
"$2a$08$Eq2r4G/76Wv39MzSX262huzPz612MZiYHVUJe/OcOql2jo4.9UxTW" },
|
78
|
-
{ "~!@#$%^&*() ~!@#$%^&*()PNBFRD",
|
79
|
-
"$2a$10$LgfYWkbzEvQ4JakH7rOvHe",
|
80
|
-
"$2a$10$LgfYWkbzEvQ4JakH7rOvHe0y8pHKF9OaFgwUZ2q7W2FFZmZzJYlfS" },
|
81
|
-
{ "~!@#$%^&*() ~!@#$%^&*()PNBFRD",
|
82
|
-
"$2a$12$WApznUOJfkEGSmYRfnkrPO",
|
83
|
-
"$2a$12$WApznUOJfkEGSmYRfnkrPOr466oFDCaj4b6HY3EXGvfxm43seyhgC" },
|
84
|
-
};
|
85
|
-
|
86
|
-
/**
|
87
|
-
* Entry point for unit tests
|
88
|
-
* @param args unused
|
89
|
-
*/
|
90
|
-
public static void main(String[] args) {
|
91
|
-
junit.textui.TestRunner.run(TestBCrypt.class);
|
92
|
-
}
|
93
|
-
|
94
|
-
/**
|
95
|
-
* Test method for 'BCrypt.hashpw(String, String)'
|
96
|
-
*/
|
97
|
-
public void testHashpw() {
|
98
|
-
System.out.print("BCrypt.hashpw(): ");
|
99
|
-
for (int i = 0; i < test_vectors.length; i++) {
|
100
|
-
String plain = test_vectors[i][0];
|
101
|
-
String salt = test_vectors[i][1];
|
102
|
-
String expected = test_vectors[i][2];
|
103
|
-
String hashed = BCrypt.hashpw(plain, salt);
|
104
|
-
assertEquals(hashed, expected);
|
105
|
-
System.out.print(".");
|
106
|
-
}
|
107
|
-
System.out.println("");
|
108
|
-
}
|
109
|
-
|
110
|
-
/**
|
111
|
-
* Test method for 'BCrypt.gensalt(int)'
|
112
|
-
*/
|
113
|
-
public void testGensaltInt() {
|
114
|
-
System.out.print("BCrypt.gensalt(log_rounds):");
|
115
|
-
for (int i = 4; i <= 12; i++) {
|
116
|
-
System.out.print(" " + Integer.toString(i) + ":");
|
117
|
-
for (int j = 0; j < test_vectors.length; j += 4) {
|
118
|
-
String plain = test_vectors[j][0];
|
119
|
-
String salt = BCrypt.gensalt(i);
|
120
|
-
String hashed1 = BCrypt.hashpw(plain, salt);
|
121
|
-
String hashed2 = BCrypt.hashpw(plain, hashed1);
|
122
|
-
assertEquals(hashed1, hashed2);
|
123
|
-
System.out.print(".");
|
124
|
-
}
|
125
|
-
}
|
126
|
-
System.out.println("");
|
127
|
-
}
|
128
|
-
|
129
|
-
/**
|
130
|
-
* Test method for 'BCrypt.gensalt()'
|
131
|
-
*/
|
132
|
-
public void testGensalt() {
|
133
|
-
System.out.print("BCrypt.gensalt(): ");
|
134
|
-
for (int i = 0; i < test_vectors.length; i += 4) {
|
135
|
-
String plain = test_vectors[i][0];
|
136
|
-
String salt = BCrypt.gensalt();
|
137
|
-
String hashed1 = BCrypt.hashpw(plain, salt);
|
138
|
-
String hashed2 = BCrypt.hashpw(plain, hashed1);
|
139
|
-
assertEquals(hashed1, hashed2);
|
140
|
-
System.out.print(".");
|
141
|
-
}
|
142
|
-
System.out.println("");
|
143
|
-
}
|
144
|
-
|
145
|
-
/**
|
146
|
-
* Test method for 'BCrypt.checkpw(String, String)'
|
147
|
-
* expecting success
|
148
|
-
*/
|
149
|
-
public void testCheckpw_success() {
|
150
|
-
System.out.print("BCrypt.checkpw w/ good passwords: ");
|
151
|
-
for (int i = 0; i < test_vectors.length; i++) {
|
152
|
-
String plain = test_vectors[i][0];
|
153
|
-
String expected = test_vectors[i][2];
|
154
|
-
assertTrue(BCrypt.checkpw(plain, expected));
|
155
|
-
System.out.print(".");
|
156
|
-
}
|
157
|
-
System.out.println("");
|
158
|
-
}
|
159
|
-
|
160
|
-
/**
|
161
|
-
* Test method for 'BCrypt.checkpw(String, String)'
|
162
|
-
* expecting failure
|
163
|
-
*/
|
164
|
-
public void testCheckpw_failure() {
|
165
|
-
System.out.print("BCrypt.checkpw w/ bad passwords: ");
|
166
|
-
for (int i = 0; i < test_vectors.length; i++) {
|
167
|
-
int broken_index = (i + 4) % test_vectors.length;
|
168
|
-
String plain = test_vectors[i][0];
|
169
|
-
String expected = test_vectors[broken_index][2];
|
170
|
-
assertFalse(BCrypt.checkpw(plain, expected));
|
171
|
-
System.out.print(".");
|
172
|
-
}
|
173
|
-
System.out.println("");
|
174
|
-
}
|
175
|
-
|
176
|
-
/**
|
177
|
-
* Test for correct hashing of non-US-ASCII passwords
|
178
|
-
*/
|
179
|
-
public void testInternationalChars() {
|
180
|
-
System.out.print("BCrypt.hashpw w/ international chars: ");
|
181
|
-
String pw1 = "ππππππππ";
|
182
|
-
String pw2 = "????????";
|
183
|
-
|
184
|
-
String h1 = BCrypt.hashpw(pw1, BCrypt.gensalt());
|
185
|
-
assertFalse(BCrypt.checkpw(pw2, h1));
|
186
|
-
System.out.print(".");
|
187
|
-
|
188
|
-
String h2 = BCrypt.hashpw(pw2, BCrypt.gensalt());
|
189
|
-
assertFalse(BCrypt.checkpw(pw1, h2));
|
190
|
-
System.out.print(".");
|
191
|
-
System.out.println("");
|
192
|
-
}
|
193
|
-
|
194
|
-
}
|
data/spec/bcrypt/engine_spec.rb
DELETED
@@ -1,82 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper"))
|
2
|
-
|
3
|
-
describe "The BCrypt engine" do
|
4
|
-
specify "should calculate the optimal cost factor to fit in a specific time" do
|
5
|
-
first = BCrypt::Engine.calibrate(100)
|
6
|
-
second = BCrypt::Engine.calibrate(400)
|
7
|
-
second.should > first
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
describe "Generating BCrypt salts" do
|
12
|
-
|
13
|
-
specify "should produce strings" do
|
14
|
-
BCrypt::Engine.generate_salt.should be_an_instance_of(String)
|
15
|
-
end
|
16
|
-
|
17
|
-
specify "should produce random data" do
|
18
|
-
BCrypt::Engine.generate_salt.should_not equal(BCrypt::Engine.generate_salt)
|
19
|
-
end
|
20
|
-
|
21
|
-
specify "should raise a InvalidCostError if the cost parameter isn't numeric" do
|
22
|
-
lambda { BCrypt::Engine.generate_salt('woo') }.should raise_error(BCrypt::Errors::InvalidCost)
|
23
|
-
end
|
24
|
-
|
25
|
-
specify "should raise a InvalidCostError if the cost parameter isn't greater than 0" do
|
26
|
-
lambda { BCrypt::Engine.generate_salt(-1) }.should raise_error(BCrypt::Errors::InvalidCost)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
describe "Autodetecting of salt cost" do
|
31
|
-
|
32
|
-
specify "should work" do
|
33
|
-
BCrypt::Engine.autodetect_cost("$2a$08$hRx2IVeHNsTSYYtUWn61Ou").should eq 8
|
34
|
-
BCrypt::Engine.autodetect_cost("$2a$05$XKd1bMnLgUnc87qvbAaCUu").should eq 5
|
35
|
-
BCrypt::Engine.autodetect_cost("$2a$13$Lni.CZ6z5A7344POTFBBV.").should eq 13
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|
39
|
-
|
40
|
-
describe "Generating BCrypt hashes" do
|
41
|
-
|
42
|
-
class MyInvalidSecret
|
43
|
-
undef to_s
|
44
|
-
end
|
45
|
-
|
46
|
-
before :each do
|
47
|
-
@salt = BCrypt::Engine.generate_salt(4)
|
48
|
-
@password = "woo"
|
49
|
-
end
|
50
|
-
|
51
|
-
specify "should produce a string" do
|
52
|
-
BCrypt::Engine.hash_secret(@password, @salt).should be_an_instance_of(String)
|
53
|
-
end
|
54
|
-
|
55
|
-
specify "should raise an InvalidSalt error if the salt is invalid" do
|
56
|
-
lambda { BCrypt::Engine.hash_secret(@password, 'nino') }.should raise_error(BCrypt::Errors::InvalidSalt)
|
57
|
-
end
|
58
|
-
|
59
|
-
specify "should raise an InvalidSecret error if the secret is invalid" do
|
60
|
-
lambda { BCrypt::Engine.hash_secret(MyInvalidSecret.new, @salt) }.should raise_error(BCrypt::Errors::InvalidSecret)
|
61
|
-
lambda { BCrypt::Engine.hash_secret(nil, @salt) }.should_not raise_error(BCrypt::Errors::InvalidSecret)
|
62
|
-
lambda { BCrypt::Engine.hash_secret(false, @salt) }.should_not raise_error(BCrypt::Errors::InvalidSecret)
|
63
|
-
end
|
64
|
-
|
65
|
-
specify "should call #to_s on the secret and use the return value as the actual secret data" do
|
66
|
-
BCrypt::Engine.hash_secret(false, @salt).should == BCrypt::Engine.hash_secret("false", @salt)
|
67
|
-
end
|
68
|
-
|
69
|
-
specify "should be interoperable with other implementations" do
|
70
|
-
# test vectors from the OpenWall implementation <http://www.openwall.com/crypt/>
|
71
|
-
test_vectors = [
|
72
|
-
["U*U", "$2a$05$CCCCCCCCCCCCCCCCCCCCC.", "$2a$05$CCCCCCCCCCCCCCCCCCCCC.E5YPO9kmyuRGyh0XouQYb4YMJKvyOeW"],
|
73
|
-
["U*U*", "$2a$05$CCCCCCCCCCCCCCCCCCCCC.", "$2a$05$CCCCCCCCCCCCCCCCCCCCC.VGOzA784oUp/Z0DY336zx7pLYAy0lwK"],
|
74
|
-
["U*U*U", "$2a$05$XXXXXXXXXXXXXXXXXXXXXO", "$2a$05$XXXXXXXXXXXXXXXXXXXXXOAcXxm9kjPGEMsLznoKqmqw7tc8WCx4a"],
|
75
|
-
["", "$2a$05$CCCCCCCCCCCCCCCCCCCCC.", "$2a$05$CCCCCCCCCCCCCCCCCCCCC.7uG0VCzI2bS7j6ymqJi9CdcdxiRTWNy"],
|
76
|
-
["0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", "$2a$05$abcdefghijklmnopqrstuu", "$2a$05$abcdefghijklmnopqrstuu5s2v8.iXieOjg/.AySBTTZIIVFJeBui"]
|
77
|
-
]
|
78
|
-
for secret, salt, test_vector in test_vectors
|
79
|
-
BCrypt::Engine.hash_secret(secret, salt).should eql(test_vector)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
data/spec/bcrypt/error_spec.rb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper"))
|
2
|
-
|
3
|
-
describe "Errors" do
|
4
|
-
|
5
|
-
shared_examples "descends from StandardError" do
|
6
|
-
it "can be rescued as a StandardError" do
|
7
|
-
described_class.should < StandardError
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
shared_examples "descends from BCrypt::Error" do
|
12
|
-
it "can be rescued as a BCrypt::Error" do
|
13
|
-
described_class.should < BCrypt::Error
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
describe BCrypt::Error do
|
18
|
-
include_examples "descends from StandardError"
|
19
|
-
end
|
20
|
-
|
21
|
-
describe BCrypt::Errors::InvalidCost do
|
22
|
-
include_examples "descends from BCrypt::Error"
|
23
|
-
end
|
24
|
-
|
25
|
-
describe BCrypt::Errors::InvalidHash do
|
26
|
-
include_examples "descends from BCrypt::Error"
|
27
|
-
end
|
28
|
-
|
29
|
-
describe BCrypt::Errors::InvalidSalt do
|
30
|
-
include_examples "descends from BCrypt::Error"
|
31
|
-
end
|
32
|
-
|
33
|
-
describe BCrypt::Errors::InvalidSecret do
|
34
|
-
include_examples "descends from BCrypt::Error"
|
35
|
-
end
|
36
|
-
|
37
|
-
end
|
@@ -1,123 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper"))
|
2
|
-
|
3
|
-
describe "Creating a hashed password" do
|
4
|
-
|
5
|
-
before :each do
|
6
|
-
@secret = "wheedle"
|
7
|
-
@password = BCrypt::Password.create(@secret, :cost => 4)
|
8
|
-
end
|
9
|
-
|
10
|
-
specify "should return a BCrypt::Password" do
|
11
|
-
@password.should be_an_instance_of(BCrypt::Password)
|
12
|
-
end
|
13
|
-
|
14
|
-
specify "should return a valid bcrypt password" do
|
15
|
-
lambda { BCrypt::Password.new(@password) }.should_not raise_error
|
16
|
-
end
|
17
|
-
|
18
|
-
specify "should behave normally if the secret is not a string" do
|
19
|
-
lambda { BCrypt::Password.create(nil) }.should_not raise_error(BCrypt::Errors::InvalidSecret)
|
20
|
-
lambda { BCrypt::Password.create({:woo => "yeah"}) }.should_not raise_error(BCrypt::Errors::InvalidSecret)
|
21
|
-
lambda { BCrypt::Password.create(false) }.should_not raise_error(BCrypt::Errors::InvalidSecret)
|
22
|
-
end
|
23
|
-
|
24
|
-
specify "should tolerate empty string secrets" do
|
25
|
-
lambda { BCrypt::Password.create( "\n".chop ) }.should_not raise_error
|
26
|
-
lambda { BCrypt::Password.create( "" ) }.should_not raise_error
|
27
|
-
lambda { BCrypt::Password.create( String.new ) }.should_not raise_error
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
describe "Reading a hashed password" do
|
32
|
-
before :each do
|
33
|
-
@secret = "U*U"
|
34
|
-
@hash = "$2a$05$CCCCCCCCCCCCCCCCCCCCC.E5YPO9kmyuRGyh0XouQYb4YMJKvyOeW"
|
35
|
-
end
|
36
|
-
|
37
|
-
specify "the cost is too damn high" do
|
38
|
-
lambda {
|
39
|
-
BCrypt::Password.create("hello", :cost => 32)
|
40
|
-
}.should raise_error(ArgumentError)
|
41
|
-
end
|
42
|
-
|
43
|
-
specify "the cost should be set to the default if nil" do
|
44
|
-
BCrypt::Password.create("hello", :cost => nil).cost.should equal(BCrypt::Engine::DEFAULT_COST)
|
45
|
-
end
|
46
|
-
|
47
|
-
specify "the cost should be set to the default if empty hash" do
|
48
|
-
BCrypt::Password.create("hello", {}).cost.should equal(BCrypt::Engine::DEFAULT_COST)
|
49
|
-
end
|
50
|
-
|
51
|
-
specify "the cost should be set to the passed value if provided" do
|
52
|
-
BCrypt::Password.create("hello", :cost => 5).cost.should equal(5)
|
53
|
-
end
|
54
|
-
|
55
|
-
specify "the cost should be set to the global value if set" do
|
56
|
-
BCrypt::Engine.cost = 5
|
57
|
-
BCrypt::Password.create("hello").cost.should equal(5)
|
58
|
-
# unset the global value to not affect other tests
|
59
|
-
BCrypt::Engine.cost = nil
|
60
|
-
end
|
61
|
-
|
62
|
-
specify "the cost should be set to an overridden constant for backwards compatibility" do
|
63
|
-
# suppress "already initialized constant" warning
|
64
|
-
old_verbose, $VERBOSE = $VERBOSE, nil
|
65
|
-
old_default_cost = BCrypt::Engine::DEFAULT_COST
|
66
|
-
|
67
|
-
BCrypt::Engine::DEFAULT_COST = 5
|
68
|
-
BCrypt::Password.create("hello").cost.should equal(5)
|
69
|
-
|
70
|
-
# reset default to not affect other tests
|
71
|
-
BCrypt::Engine::DEFAULT_COST = old_default_cost
|
72
|
-
$VERBOSE = old_verbose
|
73
|
-
end
|
74
|
-
|
75
|
-
specify "should read the version, cost, salt, and hash" do
|
76
|
-
password = BCrypt::Password.new(@hash)
|
77
|
-
password.version.should eql("2a")
|
78
|
-
password.cost.should equal(5)
|
79
|
-
password.salt.should eql("$2a$05$CCCCCCCCCCCCCCCCCCCCC.")
|
80
|
-
password.salt.class.should eq String
|
81
|
-
password.checksum.should eq("E5YPO9kmyuRGyh0XouQYb4YMJKvyOeW")
|
82
|
-
password.checksum.class.should eq String
|
83
|
-
password.to_s.should eql(@hash)
|
84
|
-
end
|
85
|
-
|
86
|
-
specify "should raise an InvalidHashError when given an invalid hash" do
|
87
|
-
lambda { BCrypt::Password.new('weedle') }.should raise_error(BCrypt::Errors::InvalidHash)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
describe "Comparing a hashed password with a secret" do
|
92
|
-
before :each do
|
93
|
-
@secret = "U*U"
|
94
|
-
@hash = "$2a$05$CCCCCCCCCCCCCCCCCCCCC.E5YPO9kmyuRGyh0XouQYb4YMJKvyOeW"
|
95
|
-
@password = BCrypt::Password.create(@secret)
|
96
|
-
end
|
97
|
-
|
98
|
-
specify "should compare successfully to the original secret" do
|
99
|
-
(@password == @secret).should be(true)
|
100
|
-
end
|
101
|
-
|
102
|
-
specify "should compare unsuccessfully to anything besides original secret" do
|
103
|
-
(@password == "@secret").should be(false)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
describe "Validating a generated salt" do
|
108
|
-
specify "should not accept an invalid salt" do
|
109
|
-
BCrypt::Engine.valid_salt?("invalid").should eq(false)
|
110
|
-
end
|
111
|
-
specify "should accept a valid salt" do
|
112
|
-
BCrypt::Engine.valid_salt?(BCrypt::Engine.generate_salt).should eq(true)
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
describe "Validating a password hash" do
|
117
|
-
specify "should not accept an invalid password" do
|
118
|
-
BCrypt::Password.valid_hash?("i_am_so_not_valid").should be_false
|
119
|
-
end
|
120
|
-
specify "should accept a valid password" do
|
121
|
-
BCrypt::Password.valid_hash?(BCrypt::Password.create "i_am_so_valid").should be_true
|
122
|
-
end
|
123
|
-
end
|