bcrypt-ruby 3.1.2 → 3.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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
@@ -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
- }
@@ -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
@@ -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