bcrypt 3.1.12 → 3.1.18
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 +5 -15
- data/.github/workflows/ruby.yml +59 -0
- data/.gitignore +1 -0
- data/CHANGELOG +87 -62
- data/README.md +15 -15
- data/Rakefile +2 -27
- data/bcrypt.gemspec +3 -5
- data/ext/jruby/bcrypt_jruby/BCrypt.java +524 -351
- data/ext/mri/bcrypt_ext.c +70 -18
- data/ext/mri/crypt.h +12 -1
- data/ext/mri/crypt_blowfish.c +269 -152
- data/ext/mri/crypt_blowfish.h +27 -0
- data/ext/mri/crypt_gensalt.c +27 -14
- data/ext/mri/crypt_gensalt.h +30 -0
- data/ext/mri/extconf.rb +6 -0
- data/ext/mri/ow-crypt.h +25 -17
- data/ext/mri/wrapper.c +338 -46
- data/ext/mri/x86.S +203 -0
- data/lib/bcrypt/engine.rb +21 -10
- data/lib/bcrypt/password.rb +14 -4
- data/lib/bcrypt.rb +1 -6
- data/spec/bcrypt/engine_spec.rb +98 -4
- data/spec/bcrypt/password_spec.rb +9 -2
- metadata +26 -39
- data/.travis.yml +0 -21
- data/Gemfile.lock +0 -44
- data/appveyor.yml +0 -50
data/ext/mri/x86.S
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Written by Solar Designer <solar at openwall.com> in 1998-2010.
|
|
3
|
+
* No copyright is claimed, and the software is hereby placed in the public
|
|
4
|
+
* domain. In case this attempt to disclaim copyright and place the software
|
|
5
|
+
* in the public domain is deemed null and void, then the software is
|
|
6
|
+
* Copyright (c) 1998-2010 Solar Designer and it is hereby released to the
|
|
7
|
+
* general public under the following terms:
|
|
8
|
+
*
|
|
9
|
+
* Redistribution and use in source and binary forms, with or without
|
|
10
|
+
* modification, are permitted.
|
|
11
|
+
*
|
|
12
|
+
* There's ABSOLUTELY NO WARRANTY, express or implied.
|
|
13
|
+
*
|
|
14
|
+
* See crypt_blowfish.c for more information.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
#ifdef __i386__
|
|
18
|
+
|
|
19
|
+
#if defined(__OpenBSD__) && !defined(__ELF__)
|
|
20
|
+
#define UNDERSCORES
|
|
21
|
+
#define ALIGN_LOG
|
|
22
|
+
#endif
|
|
23
|
+
|
|
24
|
+
#if defined(__CYGWIN32__) || defined(__MINGW32__)
|
|
25
|
+
#define UNDERSCORES
|
|
26
|
+
#endif
|
|
27
|
+
|
|
28
|
+
#ifdef __DJGPP__
|
|
29
|
+
#define UNDERSCORES
|
|
30
|
+
#define ALIGN_LOG
|
|
31
|
+
#endif
|
|
32
|
+
|
|
33
|
+
#ifdef UNDERSCORES
|
|
34
|
+
#define _BF_body_r __BF_body_r
|
|
35
|
+
#endif
|
|
36
|
+
|
|
37
|
+
#ifdef ALIGN_LOG
|
|
38
|
+
#define DO_ALIGN(log) .align (log)
|
|
39
|
+
#elif defined(DUMBAS)
|
|
40
|
+
#define DO_ALIGN(log) .align 1 << log
|
|
41
|
+
#else
|
|
42
|
+
#define DO_ALIGN(log) .align (1 << (log))
|
|
43
|
+
#endif
|
|
44
|
+
|
|
45
|
+
#define BF_FRAME 0x200
|
|
46
|
+
#define ctx %esp
|
|
47
|
+
|
|
48
|
+
#define BF_ptr (ctx)
|
|
49
|
+
|
|
50
|
+
#define S(N, r) N+BF_FRAME(ctx,r,4)
|
|
51
|
+
#ifdef DUMBAS
|
|
52
|
+
#define P(N) 0x1000+N+N+N+N+BF_FRAME(ctx)
|
|
53
|
+
#else
|
|
54
|
+
#define P(N) 0x1000+4*N+BF_FRAME(ctx)
|
|
55
|
+
#endif
|
|
56
|
+
|
|
57
|
+
/*
|
|
58
|
+
* This version of the assembly code is optimized primarily for the original
|
|
59
|
+
* Intel Pentium but is also careful to avoid partial register stalls on the
|
|
60
|
+
* Pentium Pro family of processors (tested up to Pentium III Coppermine).
|
|
61
|
+
*
|
|
62
|
+
* It is possible to do 15% faster on the Pentium Pro family and probably on
|
|
63
|
+
* many non-Intel x86 processors, but, unfortunately, that would make things
|
|
64
|
+
* twice slower for the original Pentium.
|
|
65
|
+
*
|
|
66
|
+
* An additional 2% speedup may be achieved with non-reentrant code.
|
|
67
|
+
*/
|
|
68
|
+
|
|
69
|
+
#define L %esi
|
|
70
|
+
#define R %edi
|
|
71
|
+
#define tmp1 %eax
|
|
72
|
+
#define tmp1_lo %al
|
|
73
|
+
#define tmp2 %ecx
|
|
74
|
+
#define tmp2_hi %ch
|
|
75
|
+
#define tmp3 %edx
|
|
76
|
+
#define tmp3_lo %dl
|
|
77
|
+
#define tmp4 %ebx
|
|
78
|
+
#define tmp4_hi %bh
|
|
79
|
+
#define tmp5 %ebp
|
|
80
|
+
|
|
81
|
+
.text
|
|
82
|
+
|
|
83
|
+
#define BF_ROUND(L, R, N) \
|
|
84
|
+
xorl L,tmp2; \
|
|
85
|
+
xorl tmp1,tmp1; \
|
|
86
|
+
movl tmp2,L; \
|
|
87
|
+
shrl $16,tmp2; \
|
|
88
|
+
movl L,tmp4; \
|
|
89
|
+
movb tmp2_hi,tmp1_lo; \
|
|
90
|
+
andl $0xFF,tmp2; \
|
|
91
|
+
movb tmp4_hi,tmp3_lo; \
|
|
92
|
+
andl $0xFF,tmp4; \
|
|
93
|
+
movl S(0,tmp1),tmp1; \
|
|
94
|
+
movl S(0x400,tmp2),tmp5; \
|
|
95
|
+
addl tmp5,tmp1; \
|
|
96
|
+
movl S(0x800,tmp3),tmp5; \
|
|
97
|
+
xorl tmp5,tmp1; \
|
|
98
|
+
movl S(0xC00,tmp4),tmp5; \
|
|
99
|
+
addl tmp1,tmp5; \
|
|
100
|
+
movl 4+P(N),tmp2; \
|
|
101
|
+
xorl tmp5,R
|
|
102
|
+
|
|
103
|
+
#define BF_ENCRYPT_START \
|
|
104
|
+
BF_ROUND(L, R, 0); \
|
|
105
|
+
BF_ROUND(R, L, 1); \
|
|
106
|
+
BF_ROUND(L, R, 2); \
|
|
107
|
+
BF_ROUND(R, L, 3); \
|
|
108
|
+
BF_ROUND(L, R, 4); \
|
|
109
|
+
BF_ROUND(R, L, 5); \
|
|
110
|
+
BF_ROUND(L, R, 6); \
|
|
111
|
+
BF_ROUND(R, L, 7); \
|
|
112
|
+
BF_ROUND(L, R, 8); \
|
|
113
|
+
BF_ROUND(R, L, 9); \
|
|
114
|
+
BF_ROUND(L, R, 10); \
|
|
115
|
+
BF_ROUND(R, L, 11); \
|
|
116
|
+
BF_ROUND(L, R, 12); \
|
|
117
|
+
BF_ROUND(R, L, 13); \
|
|
118
|
+
BF_ROUND(L, R, 14); \
|
|
119
|
+
BF_ROUND(R, L, 15); \
|
|
120
|
+
movl BF_ptr,tmp5; \
|
|
121
|
+
xorl L,tmp2; \
|
|
122
|
+
movl P(17),L
|
|
123
|
+
|
|
124
|
+
#define BF_ENCRYPT_END \
|
|
125
|
+
xorl R,L; \
|
|
126
|
+
movl tmp2,R
|
|
127
|
+
|
|
128
|
+
DO_ALIGN(5)
|
|
129
|
+
.globl _BF_body_r
|
|
130
|
+
_BF_body_r:
|
|
131
|
+
movl 4(%esp),%eax
|
|
132
|
+
pushl %ebp
|
|
133
|
+
pushl %ebx
|
|
134
|
+
pushl %esi
|
|
135
|
+
pushl %edi
|
|
136
|
+
subl $BF_FRAME-8,%eax
|
|
137
|
+
xorl L,L
|
|
138
|
+
cmpl %esp,%eax
|
|
139
|
+
ja BF_die
|
|
140
|
+
xchgl %eax,%esp
|
|
141
|
+
xorl R,R
|
|
142
|
+
pushl %eax
|
|
143
|
+
leal 0x1000+BF_FRAME-4(ctx),%eax
|
|
144
|
+
movl 0x1000+BF_FRAME-4(ctx),tmp2
|
|
145
|
+
pushl %eax
|
|
146
|
+
xorl tmp3,tmp3
|
|
147
|
+
BF_loop_P:
|
|
148
|
+
BF_ENCRYPT_START
|
|
149
|
+
addl $8,tmp5
|
|
150
|
+
BF_ENCRYPT_END
|
|
151
|
+
leal 0x1000+18*4+BF_FRAME(ctx),tmp1
|
|
152
|
+
movl tmp5,BF_ptr
|
|
153
|
+
cmpl tmp5,tmp1
|
|
154
|
+
movl L,-8(tmp5)
|
|
155
|
+
movl R,-4(tmp5)
|
|
156
|
+
movl P(0),tmp2
|
|
157
|
+
ja BF_loop_P
|
|
158
|
+
leal BF_FRAME(ctx),tmp5
|
|
159
|
+
xorl tmp3,tmp3
|
|
160
|
+
movl tmp5,BF_ptr
|
|
161
|
+
BF_loop_S:
|
|
162
|
+
BF_ENCRYPT_START
|
|
163
|
+
BF_ENCRYPT_END
|
|
164
|
+
movl P(0),tmp2
|
|
165
|
+
movl L,(tmp5)
|
|
166
|
+
movl R,4(tmp5)
|
|
167
|
+
BF_ENCRYPT_START
|
|
168
|
+
BF_ENCRYPT_END
|
|
169
|
+
movl P(0),tmp2
|
|
170
|
+
movl L,8(tmp5)
|
|
171
|
+
movl R,12(tmp5)
|
|
172
|
+
BF_ENCRYPT_START
|
|
173
|
+
BF_ENCRYPT_END
|
|
174
|
+
movl P(0),tmp2
|
|
175
|
+
movl L,16(tmp5)
|
|
176
|
+
movl R,20(tmp5)
|
|
177
|
+
BF_ENCRYPT_START
|
|
178
|
+
addl $32,tmp5
|
|
179
|
+
BF_ENCRYPT_END
|
|
180
|
+
leal 0x1000+BF_FRAME(ctx),tmp1
|
|
181
|
+
movl tmp5,BF_ptr
|
|
182
|
+
cmpl tmp5,tmp1
|
|
183
|
+
movl P(0),tmp2
|
|
184
|
+
movl L,-8(tmp5)
|
|
185
|
+
movl R,-4(tmp5)
|
|
186
|
+
ja BF_loop_S
|
|
187
|
+
movl 4(%esp),%esp
|
|
188
|
+
popl %edi
|
|
189
|
+
popl %esi
|
|
190
|
+
popl %ebx
|
|
191
|
+
popl %ebp
|
|
192
|
+
ret
|
|
193
|
+
|
|
194
|
+
BF_die:
|
|
195
|
+
/* Oops, need to re-compile with a larger BF_FRAME. */
|
|
196
|
+
hlt
|
|
197
|
+
jmp BF_die
|
|
198
|
+
|
|
199
|
+
#endif
|
|
200
|
+
|
|
201
|
+
#if defined(__ELF__) && defined(__linux__)
|
|
202
|
+
.section .note.GNU-stack,"",%progbits
|
|
203
|
+
#endif
|
data/lib/bcrypt/engine.rb
CHANGED
|
@@ -2,9 +2,19 @@ module BCrypt
|
|
|
2
2
|
# A Ruby wrapper for the bcrypt() C extension calls and the Java calls.
|
|
3
3
|
class Engine
|
|
4
4
|
# The default computational expense parameter.
|
|
5
|
-
DEFAULT_COST =
|
|
5
|
+
DEFAULT_COST = 12
|
|
6
6
|
# The minimum cost supported by the algorithm.
|
|
7
7
|
MIN_COST = 4
|
|
8
|
+
# The maximum cost supported by the algorithm.
|
|
9
|
+
MAX_COST = 31
|
|
10
|
+
# Maximum possible size of bcrypt() secrets.
|
|
11
|
+
# Older versions of the bcrypt library would truncate passwords longer
|
|
12
|
+
# than 72 bytes, but newer ones do not. We truncate like the old library for
|
|
13
|
+
# forward compatibility. This way users upgrading from Ubuntu 18.04 to 20.04
|
|
14
|
+
# will not have their user passwords invalidated, for example.
|
|
15
|
+
# A max secret length greater than 255 leads to bcrypt returning nil.
|
|
16
|
+
# https://github.com/bcrypt-ruby/bcrypt-ruby/issues/225#issuecomment-875908425
|
|
17
|
+
MAX_SECRET_BYTESIZE = 72
|
|
8
18
|
# Maximum possible size of bcrypt() salts.
|
|
9
19
|
MAX_SALT_LENGTH = 16
|
|
10
20
|
|
|
@@ -28,8 +38,8 @@ module BCrypt
|
|
|
28
38
|
#
|
|
29
39
|
# Example:
|
|
30
40
|
#
|
|
31
|
-
# BCrypt::Engine::DEFAULT_COST #=>
|
|
32
|
-
# BCrypt::Password.create('secret').cost #=>
|
|
41
|
+
# BCrypt::Engine::DEFAULT_COST #=> 12
|
|
42
|
+
# BCrypt::Password.create('secret').cost #=> 12
|
|
33
43
|
#
|
|
34
44
|
# BCrypt::Engine.cost = 8
|
|
35
45
|
# BCrypt::Password.create('secret').cost #=> 8
|
|
@@ -41,14 +51,16 @@ module BCrypt
|
|
|
41
51
|
end
|
|
42
52
|
|
|
43
53
|
# Given a secret and a valid salt (see BCrypt::Engine.generate_salt) calculates
|
|
44
|
-
# a bcrypt() password hash.
|
|
54
|
+
# a bcrypt() password hash. Secrets longer than 72 bytes are truncated.
|
|
45
55
|
def self.hash_secret(secret, salt, _ = nil)
|
|
46
56
|
if valid_secret?(secret)
|
|
47
57
|
if valid_salt?(salt)
|
|
48
58
|
if RUBY_PLATFORM == "java"
|
|
49
|
-
Java.bcrypt_jruby.BCrypt.hashpw(secret.to_s, salt.to_s)
|
|
59
|
+
Java.bcrypt_jruby.BCrypt.hashpw(secret.to_s.to_java_bytes, salt.to_s)
|
|
50
60
|
else
|
|
51
|
-
|
|
61
|
+
secret = secret.to_s
|
|
62
|
+
secret = secret.byteslice(0, MAX_SECRET_BYTESIZE) if secret && secret.bytesize > MAX_SECRET_BYTESIZE
|
|
63
|
+
__bc_crypt(secret, salt)
|
|
52
64
|
end
|
|
53
65
|
else
|
|
54
66
|
raise Errors::InvalidSalt.new("invalid salt")
|
|
@@ -68,8 +80,7 @@ module BCrypt
|
|
|
68
80
|
if RUBY_PLATFORM == "java"
|
|
69
81
|
Java.bcrypt_jruby.BCrypt.gensalt(cost)
|
|
70
82
|
else
|
|
71
|
-
|
|
72
|
-
__bc_salt(prefix, cost, OpenSSL::Random.random_bytes(MAX_SALT_LENGTH))
|
|
83
|
+
__bc_salt("$2a$", cost, OpenSSL::Random.random_bytes(MAX_SALT_LENGTH))
|
|
73
84
|
end
|
|
74
85
|
else
|
|
75
86
|
raise Errors::InvalidCost.new("cost must be numeric and > 0")
|
|
@@ -78,7 +89,7 @@ module BCrypt
|
|
|
78
89
|
|
|
79
90
|
# Returns true if +salt+ is a valid bcrypt() salt, false if not.
|
|
80
91
|
def self.valid_salt?(salt)
|
|
81
|
-
!!(salt =~
|
|
92
|
+
!!(salt =~ /\A\$[0-9a-z]{2,}\$[0-9]{2,}\$[A-Za-z0-9\.\/]{22,}\z/)
|
|
82
93
|
end
|
|
83
94
|
|
|
84
95
|
# Returns true if +secret+ is a valid bcrypt() secret, false if not.
|
|
@@ -99,7 +110,7 @@ module BCrypt
|
|
|
99
110
|
# # should take less than 1000ms
|
|
100
111
|
# BCrypt::Password.create("woo", :cost => 12)
|
|
101
112
|
def self.calibrate(upper_time_limit_in_ms)
|
|
102
|
-
|
|
113
|
+
(BCrypt::Engine::MIN_COST..BCrypt::Engine::MAX_COST-1).each do |i|
|
|
103
114
|
start_time = Time.now
|
|
104
115
|
Password.create("testing testing", :cost => i+1)
|
|
105
116
|
end_time = Time.now - start_time
|
data/lib/bcrypt/password.rb
CHANGED
|
@@ -7,7 +7,7 @@ module BCrypt
|
|
|
7
7
|
#
|
|
8
8
|
# # hash a user's password
|
|
9
9
|
# @password = Password.create("my grand secret")
|
|
10
|
-
# @password #=> "$2a$
|
|
10
|
+
# @password #=> "$2a$12$C5.FIvVDS9W4AYZ/Ib37YuWd/7ozp1UaMhU28UKrfSxp2oDchbi3K"
|
|
11
11
|
#
|
|
12
12
|
# # store it safely
|
|
13
13
|
# @user.update_attribute(:password, @password)
|
|
@@ -42,12 +42,12 @@ module BCrypt
|
|
|
42
42
|
# @password = BCrypt::Password.create("my secret", :cost => 13)
|
|
43
43
|
def create(secret, options = {})
|
|
44
44
|
cost = options[:cost] || BCrypt::Engine.cost
|
|
45
|
-
raise ArgumentError if cost >
|
|
45
|
+
raise ArgumentError if cost > BCrypt::Engine::MAX_COST
|
|
46
46
|
Password.new(BCrypt::Engine.hash_secret(secret, BCrypt::Engine.generate_salt(cost)))
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
def valid_hash?(h)
|
|
50
|
-
|
|
50
|
+
/\A\$[0-9a-z]{2}\$[0-9]{2}\$[A-Za-z0-9\.\/]{53}\z/ === h
|
|
51
51
|
end
|
|
52
52
|
end
|
|
53
53
|
|
|
@@ -62,6 +62,17 @@ module BCrypt
|
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
# Compares a potential secret against the hash. Returns true if the secret is the original secret, false otherwise.
|
|
65
|
+
#
|
|
66
|
+
# Comparison edge case/gotcha:
|
|
67
|
+
#
|
|
68
|
+
# secret = "my secret"
|
|
69
|
+
# @password = BCrypt::Password.create(secret)
|
|
70
|
+
#
|
|
71
|
+
# @password == secret # => True
|
|
72
|
+
# @password == @password # => False
|
|
73
|
+
# @password == @password.to_s # => False
|
|
74
|
+
# @password.to_s == @password # => True
|
|
75
|
+
# @password.to_s == @password.to_s # => True
|
|
65
76
|
def ==(secret)
|
|
66
77
|
super(BCrypt::Engine.hash_secret(secret, @salt))
|
|
67
78
|
end
|
|
@@ -83,5 +94,4 @@ module BCrypt
|
|
|
83
94
|
return v.to_str, c.to_i, h[0, 29].to_str, mash[-31, 31].to_str
|
|
84
95
|
end
|
|
85
96
|
end
|
|
86
|
-
|
|
87
97
|
end
|
data/lib/bcrypt.rb
CHANGED
data/spec/bcrypt/engine_spec.rb
CHANGED
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper"))
|
|
2
|
+
require 'securerandom'
|
|
3
|
+
|
|
4
|
+
describe 'BCrypt::Engine' do
|
|
5
|
+
describe '.calibrate(upper_time_limit_in_ms)' do
|
|
6
|
+
context 'a tiny upper time limit provided' do
|
|
7
|
+
it 'returns a minimum cost supported by the algorithm' do
|
|
8
|
+
expect(BCrypt::Engine.calibrate(0.001)).to eq(4)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
2
13
|
|
|
3
14
|
describe "The BCrypt engine" do
|
|
4
15
|
specify "should calculate the optimal cost factor to fit in a specific time" do
|
|
5
|
-
|
|
6
|
-
|
|
16
|
+
start_time = Time.now
|
|
17
|
+
BCrypt::Password.create("testing testing", :cost => BCrypt::Engine::MIN_COST + 1)
|
|
18
|
+
min_time_ms = (Time.now - start_time) * 1000
|
|
19
|
+
first = BCrypt::Engine.calibrate(min_time_ms)
|
|
20
|
+
second = BCrypt::Engine.calibrate(min_time_ms * 4)
|
|
7
21
|
expect(second).to be > first
|
|
8
22
|
end
|
|
9
23
|
end
|
|
@@ -67,16 +81,96 @@ describe "Generating BCrypt hashes" do
|
|
|
67
81
|
end
|
|
68
82
|
|
|
69
83
|
specify "should be interoperable with other implementations" do
|
|
70
|
-
# test vectors from the OpenWall implementation <http://www.openwall.com/crypt/>
|
|
71
84
|
test_vectors = [
|
|
85
|
+
# test vectors from the OpenWall implementation <https://www.openwall.com/crypt/>, found in wrapper.c
|
|
72
86
|
["U*U", "$2a$05$CCCCCCCCCCCCCCCCCCCCC.", "$2a$05$CCCCCCCCCCCCCCCCCCCCC.E5YPO9kmyuRGyh0XouQYb4YMJKvyOeW"],
|
|
73
87
|
["U*U*", "$2a$05$CCCCCCCCCCCCCCCCCCCCC.", "$2a$05$CCCCCCCCCCCCCCCCCCCCC.VGOzA784oUp/Z0DY336zx7pLYAy0lwK"],
|
|
74
88
|
["U*U*U", "$2a$05$XXXXXXXXXXXXXXXXXXXXXO", "$2a$05$XXXXXXXXXXXXXXXXXXXXXOAcXxm9kjPGEMsLznoKqmqw7tc8WCx4a"],
|
|
89
|
+
["0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789chars after 72 are ignored", "$2a$05$abcdefghijklmnopqrstuu", "$2a$05$abcdefghijklmnopqrstuu5s2v8.iXieOjg/.AySBTTZIIVFJeBui"],
|
|
90
|
+
["\xa3", "$2x$05$/OK.fbVrR/bpIqNJ5ianF.", "$2x$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e"],
|
|
91
|
+
["\xff\xff\xa3", "$2x$05$/OK.fbVrR/bpIqNJ5ianF.", "$2x$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e"],
|
|
92
|
+
["\xff\xff\xa3", "$2y$05$/OK.fbVrR/bpIqNJ5ianF.", "$2y$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e"],
|
|
93
|
+
["\xff\xff\xa3", "$2a$05$/OK.fbVrR/bpIqNJ5ianF.", "$2a$05$/OK.fbVrR/bpIqNJ5ianF.nqd1wy.pTMdcvrRWxyiGL2eMz.2a85."],
|
|
94
|
+
["\xff\xff\xa3", "$2b$05$/OK.fbVrR/bpIqNJ5ianF.", "$2b$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e"],
|
|
95
|
+
["\xa3", "$2y$05$/OK.fbVrR/bpIqNJ5ianF.", "$2y$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq"],
|
|
96
|
+
["\xa3", "$2a$05$/OK.fbVrR/bpIqNJ5ianF.", "$2a$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq"],
|
|
97
|
+
["\xa3", "$2b$05$/OK.fbVrR/bpIqNJ5ianF.", "$2b$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq"],
|
|
98
|
+
["1\xa3" "345", "$2x$05$/OK.fbVrR/bpIqNJ5ianF.", "$2x$05$/OK.fbVrR/bpIqNJ5ianF.o./n25XVfn6oAPaUvHe.Csk4zRfsYPi"],
|
|
99
|
+
["\xff\xa3" "345", "$2x$05$/OK.fbVrR/bpIqNJ5ianF.", "$2x$05$/OK.fbVrR/bpIqNJ5ianF.o./n25XVfn6oAPaUvHe.Csk4zRfsYPi"],
|
|
100
|
+
["\xff\xa3" "34" "\xff\xff\xff\xa3" "345", "$2x$05$/OK.fbVrR/bpIqNJ5ianF.", "$2x$05$/OK.fbVrR/bpIqNJ5ianF.o./n25XVfn6oAPaUvHe.Csk4zRfsYPi"],
|
|
101
|
+
["\xff\xa3" "34" "\xff\xff\xff\xa3" "345", "$2y$05$/OK.fbVrR/bpIqNJ5ianF.", "$2y$05$/OK.fbVrR/bpIqNJ5ianF.o./n25XVfn6oAPaUvHe.Csk4zRfsYPi"],
|
|
102
|
+
["\xff\xa3" "34" "\xff\xff\xff\xa3" "345", "$2a$05$/OK.fbVrR/bpIqNJ5ianF.", "$2a$05$/OK.fbVrR/bpIqNJ5ianF.ZC1JEJ8Z4gPfpe1JOr/oyPXTWl9EFd."],
|
|
103
|
+
["\xff\xa3" "345", "$2y$05$/OK.fbVrR/bpIqNJ5ianF.", "$2y$05$/OK.fbVrR/bpIqNJ5ianF.nRht2l/HRhr6zmCp9vYUvvsqynflf9e"],
|
|
104
|
+
["\xff\xa3" "345", "$2a$05$/OK.fbVrR/bpIqNJ5ianF.", "$2a$05$/OK.fbVrR/bpIqNJ5ianF.nRht2l/HRhr6zmCp9vYUvvsqynflf9e"],
|
|
105
|
+
["\xa3" "ab", "$2a$05$/OK.fbVrR/bpIqNJ5ianF.", "$2a$05$/OK.fbVrR/bpIqNJ5ianF.6IflQkJytoRVc1yuaNtHfiuq.FRlSIS"],
|
|
106
|
+
["\xa3" "ab", "$2x$05$/OK.fbVrR/bpIqNJ5ianF.", "$2x$05$/OK.fbVrR/bpIqNJ5ianF.6IflQkJytoRVc1yuaNtHfiuq.FRlSIS"],
|
|
107
|
+
["\xa3" "ab", "$2y$05$/OK.fbVrR/bpIqNJ5ianF.", "$2y$05$/OK.fbVrR/bpIqNJ5ianF.6IflQkJytoRVc1yuaNtHfiuq.FRlSIS"],
|
|
108
|
+
["\xd1\x91", "$2x$05$6bNw2HLQYeqHYyBfLMsv/O", "$2x$05$6bNw2HLQYeqHYyBfLMsv/OiwqTymGIGzFsA4hOTWebfehXHNprcAS"],
|
|
109
|
+
["\xd0\xc1\xd2\xcf\xcc\xd8", "$2x$05$6bNw2HLQYeqHYyBfLMsv/O", "$2x$05$6bNw2HLQYeqHYyBfLMsv/O9LIGgn8OMzuDoHfof8AQimSGfcSWxnS"],
|
|
110
|
+
["\xaa"*72+"chars after 72 are ignored as usual", "$2a$05$/OK.fbVrR/bpIqNJ5ianF.", "$2a$05$/OK.fbVrR/bpIqNJ5ianF.swQOIzjOiJ9GHEPuhEkvqrUyvWhEMx6"],
|
|
111
|
+
["\xaa\x55"*36, "$2a$05$/OK.fbVrR/bpIqNJ5ianF.", "$2a$05$/OK.fbVrR/bpIqNJ5ianF.R9xrDjiycxMbQE2bp.vgqlYpW5wx2yy"],
|
|
112
|
+
["\x55\xaa\xff"*24, "$2a$05$/OK.fbVrR/bpIqNJ5ianF.", "$2a$05$/OK.fbVrR/bpIqNJ5ianF.9tQZzcJfm3uj2NvJ/n5xkhpqLrMpWCe"],
|
|
75
113
|
["", "$2a$05$CCCCCCCCCCCCCCCCCCCCC.", "$2a$05$CCCCCCCCCCCCCCCCCCCCC.7uG0VCzI2bS7j6ymqJi9CdcdxiRTWNy"],
|
|
76
|
-
|
|
114
|
+
|
|
115
|
+
# test vectors from the Java implementation, found in https://github.com/spring-projects/spring-security/blob/master/crypto/src/test/java/org/springframework/security/crypto/bcrypt/BCryptTests.java
|
|
116
|
+
["", "$2a$06$DCq7YPn5Rq63x1Lad4cll.", "$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s."],
|
|
117
|
+
["", "$2a$08$HqWuK6/Ng6sg9gQzbLrgb.", "$2a$08$HqWuK6/Ng6sg9gQzbLrgb.Tl.ZHfXLhvt/SgVyWhQqgqcZ7ZuUtye"],
|
|
118
|
+
["", "$2a$10$k1wbIrmNyFAPwPVPSVa/ze", "$2a$10$k1wbIrmNyFAPwPVPSVa/zecw2BCEnBwVS2GbrmgzxFUOqW9dk4TCW"],
|
|
119
|
+
["", "$2a$12$k42ZFHFWqBp3vWli.nIn8u", "$2a$12$k42ZFHFWqBp3vWli.nIn8uYyIkbvYRvodzbfbK18SSsY.CsIQPlxO"],
|
|
120
|
+
["", "$2b$06$8eVN9RiU8Yki430X.wBvN.", "$2b$06$8eVN9RiU8Yki430X.wBvN.LWaqh2962emLVSVXVZIXJvDYLsV0oFu"],
|
|
121
|
+
["", "$2b$06$NlgfNgpIc6GlHciCkMEW8u", "$2b$06$NlgfNgpIc6GlHciCkMEW8uKOBsyvAp7QwlHpysOlKdtyEw50WQua2"],
|
|
122
|
+
["", "$2y$06$mFDtkz6UN7B3GZ2qi2hhaO", "$2y$06$mFDtkz6UN7B3GZ2qi2hhaO3OFWzNEdcY84ELw6iHCPruuQfSAXBLK"],
|
|
123
|
+
["", "$2y$06$88kSqVttBx.e9iXTPCLa5u", "$2y$06$88kSqVttBx.e9iXTPCLa5uFPrVFjfLH4D.KcO6pBiAmvUkvdg0EYy"],
|
|
124
|
+
["a", "$2a$06$m0CrhHm10qJ3lXRY.5zDGO", "$2a$06$m0CrhHm10qJ3lXRY.5zDGO3rS2KdeeWLuGmsfGlMfOxih58VYVfxe"],
|
|
125
|
+
["a", "$2a$08$cfcvVd2aQ8CMvoMpP2EBfe", "$2a$08$cfcvVd2aQ8CMvoMpP2EBfeodLEkkFJ9umNEfPD18.hUF62qqlC/V."],
|
|
126
|
+
["a", "$2a$10$k87L/MF28Q673VKh8/cPi.", "$2a$10$k87L/MF28Q673VKh8/cPi.SUl7MU/rWuSiIDDFayrKk/1tBsSQu4u"],
|
|
127
|
+
["a", "$2a$12$8NJH3LsPrANStV6XtBakCe", "$2a$12$8NJH3LsPrANStV6XtBakCez0cKHXVxmvxIlcz785vxAIZrihHZpeS"],
|
|
128
|
+
["a", "$2b$06$ehKGYiS4wt2HAr7KQXS5z.", "$2b$06$ehKGYiS4wt2HAr7KQXS5z.OaRjB4jHO7rBHJKlGXbqEH3QVJfO7iO"],
|
|
129
|
+
["a", "$2b$06$PWxFFHA3HiCD46TNOZh30e", "$2b$06$PWxFFHA3HiCD46TNOZh30eNto1hg5uM9tHBlI4q/b03SW/gGKUYk6"],
|
|
130
|
+
["a", "$2y$06$LUdD6/aD0e/UbnxVAVbvGu", "$2y$06$LUdD6/aD0e/UbnxVAVbvGuUmIoJ3l/OK94ThhadpMWwKC34LrGEey"],
|
|
131
|
+
["a", "$2y$06$eqgY.T2yloESMZxgp76deO", "$2y$06$eqgY.T2yloESMZxgp76deOROa7nzXDxbO0k.PJvuClTa.Vu1AuemG"],
|
|
132
|
+
["abc", "$2a$06$If6bvum7DFjUnE9p2uDeDu", "$2a$06$If6bvum7DFjUnE9p2uDeDu0YHzrHM6tf.iqN8.yx.jNN1ILEf7h0i"],
|
|
133
|
+
["abc", "$2a$08$Ro0CUfOqk6cXEKf3dyaM7O", "$2a$08$Ro0CUfOqk6cXEKf3dyaM7OhSCvnwM9s4wIX9JeLapehKK5YdLxKcm"],
|
|
134
|
+
["abc", "$2a$10$WvvTPHKwdBJ3uk0Z37EMR.", "$2a$10$WvvTPHKwdBJ3uk0Z37EMR.hLA2W6N9AEBhEgrAOljy2Ae5MtaSIUi"],
|
|
135
|
+
["abc", "$2a$12$EXRkfkdmXn2gzds2SSitu.", "$2a$12$EXRkfkdmXn2gzds2SSitu.MW9.gAVqa9eLS1//RYtYCmB1eLHg.9q"],
|
|
136
|
+
["abc", "$2b$06$5FyQoicpbox1xSHFfhhdXu", "$2b$06$5FyQoicpbox1xSHFfhhdXuR2oxLpO1rYsQh5RTkI/9.RIjtoF0/ta"],
|
|
137
|
+
["abc", "$2b$06$1kJyuho8MCVP3HHsjnRMkO", "$2b$06$1kJyuho8MCVP3HHsjnRMkO1nvCOaKTqLnjG2TX1lyMFbXH/aOkgc."],
|
|
138
|
+
["abc", "$2y$06$ACfku9dT6.H8VjdKb8nhlu", "$2y$06$ACfku9dT6.H8VjdKb8nhluaoBmhJyK7GfoNScEfOfrJffUxoUeCjK"],
|
|
139
|
+
["abc", "$2y$06$9JujYcoWPmifvFA3RUP90e", "$2y$06$9JujYcoWPmifvFA3RUP90e5rSEHAb5Ye6iv3.G9ikiHNv5cxjNEse"],
|
|
140
|
+
["abcdefghijklmnopqrstuvwxyz", "$2a$06$.rCVZVOThsIa97pEDOxvGu", "$2a$06$.rCVZVOThsIa97pEDOxvGuRRgzG64bvtJ0938xuqzv18d3ZpQhstC"],
|
|
141
|
+
["abcdefghijklmnopqrstuvwxyz", "$2a$08$aTsUwsyowQuzRrDqFflhge", "$2a$08$aTsUwsyowQuzRrDqFflhgekJ8d9/7Z3GV3UcgvzQW3J5zMyrTvlz."],
|
|
142
|
+
["abcdefghijklmnopqrstuvwxyz", "$2a$10$fVH8e28OQRj9tqiDXs1e1u", "$2a$10$fVH8e28OQRj9tqiDXs1e1uxpsjN0c7II7YPKXua2NAKYvM6iQk7dq"],
|
|
143
|
+
["abcdefghijklmnopqrstuvwxyz", "$2a$12$D4G5f18o7aMMfwasBL7Gpu", "$2a$12$D4G5f18o7aMMfwasBL7GpuQWuP3pkrZrOAnqP.bmezbMng.QwJ/pG"],
|
|
144
|
+
["abcdefghijklmnopqrstuvwxyz", "$2b$06$O8E89AQPj1zJQA05YvIAU.", "$2b$06$O8E89AQPj1zJQA05YvIAU.hMpj25BXri1bupl/Q7CJMlpLwZDNBoO"],
|
|
145
|
+
["abcdefghijklmnopqrstuvwxyz", "$2b$06$PDqIWr./o/P3EE/P.Q0A/u", "$2b$06$PDqIWr./o/P3EE/P.Q0A/uFg86WL/PXTbaW267TDALEwDylqk00Z."],
|
|
146
|
+
["abcdefghijklmnopqrstuvwxyz", "$2y$06$34MG90ZLah8/ZNr3ltlHCu", "$2y$06$34MG90ZLah8/ZNr3ltlHCuz6bachF8/3S5jTuzF1h2qg2cUk11sFW"],
|
|
147
|
+
["abcdefghijklmnopqrstuvwxyz", "$2y$06$AK.hSLfMyw706iEW24i68u", "$2y$06$AK.hSLfMyw706iEW24i68uKAc2yorPTrB0cimvjJHEBUrPkOq7VvG"],
|
|
148
|
+
["~!@#$%^&*() ~!@#$%^&*()PNBFRD", "$2a$06$fPIsBO8qRqkjj273rfaOI.", "$2a$06$fPIsBO8qRqkjj273rfaOI.HtSV9jLDpTbZn782DC6/t7qT67P6FfO"],
|
|
149
|
+
["~!@#$%^&*() ~!@#$%^&*()PNBFRD", "$2a$08$Eq2r4G/76Wv39MzSX262hu", "$2a$08$Eq2r4G/76Wv39MzSX262huzPz612MZiYHVUJe/OcOql2jo4.9UxTW"],
|
|
150
|
+
["~!@#$%^&*() ~!@#$%^&*()PNBFRD", "$2a$10$LgfYWkbzEvQ4JakH7rOvHe", "$2a$10$LgfYWkbzEvQ4JakH7rOvHe0y8pHKF9OaFgwUZ2q7W2FFZmZzJYlfS"],
|
|
151
|
+
["~!@#$%^&*() ~!@#$%^&*()PNBFRD", "$2a$12$WApznUOJfkEGSmYRfnkrPO", "$2a$12$WApznUOJfkEGSmYRfnkrPOr466oFDCaj4b6HY3EXGvfxm43seyhgC"],
|
|
152
|
+
["~!@#$%^&*() ~!@#$%^&*()PNBFRD", "$2b$06$FGWA8OlY6RtQhXBXuCJ8Wu", "$2b$06$FGWA8OlY6RtQhXBXuCJ8WusVipRI15cWOgJK8MYpBHEkktMfbHRIG"],
|
|
153
|
+
["~!@#$%^&*() ~!@#$%^&*()PNBFRD", "$2b$06$G6aYU7UhUEUDJBdTgq3CRe", "$2b$06$G6aYU7UhUEUDJBdTgq3CRekiopCN4O4sNitFXrf5NUscsVZj3a2r6"],
|
|
154
|
+
["~!@#$%^&*() ~!@#$%^&*()PNBFRD", "$2y$06$sYDFHqOcXTjBgOsqC0WCKe", "$2y$06$sYDFHqOcXTjBgOsqC0WCKeMd3T1UhHuWQSxncLGtXDLMrcE6vFDti"],
|
|
155
|
+
["~!@#$%^&*() ~!@#$%^&*()PNBFRD", "$2y$06$6Xm0gCw4g7ZNDCEp4yTise", "$2y$06$6Xm0gCw4g7ZNDCEp4yTisez0kSdpXEl66MvdxGidnmChIe8dFmMnq"]
|
|
77
156
|
]
|
|
78
157
|
for secret, salt, test_vector in test_vectors
|
|
79
158
|
expect(BCrypt::Engine.hash_secret(secret, salt)).to eql(test_vector)
|
|
80
159
|
end
|
|
81
160
|
end
|
|
161
|
+
|
|
162
|
+
specify "should truncate long 1-byte character secrets to 72 bytes" do
|
|
163
|
+
# 'b' as a base triggers the failure at 256 characters, but 'a' does not.
|
|
164
|
+
too_long_secret = 'b'*(BCrypt::Engine::MAX_SECRET_BYTESIZE + 1)
|
|
165
|
+
just_right_secret = 'b'*BCrypt::Engine::MAX_SECRET_BYTESIZE
|
|
166
|
+
expect(BCrypt::Engine.hash_secret(too_long_secret, @salt)).to eq(BCrypt::Engine.hash_secret(just_right_secret, @salt))
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
specify "should truncate long multi-byte character secrets to 72 bytes" do
|
|
170
|
+
# 256 times causes bcrypt to return nil for libxcrypt > 4.4.18-4.
|
|
171
|
+
too_long_secret = '𐐷'*256
|
|
172
|
+
# 𐐷 takes 4 bytes in UTF-8. 18 times is 72 bytes
|
|
173
|
+
just_right_secret = '𐐷'*18
|
|
174
|
+
expect(BCrypt::Engine.hash_secret(too_long_secret, @salt)).to eq(BCrypt::Engine.hash_secret(just_right_secret, @salt))
|
|
175
|
+
end
|
|
82
176
|
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper"))
|
|
2
|
+
require 'securerandom'
|
|
2
3
|
|
|
3
4
|
describe "Creating a hashed password" do
|
|
4
5
|
|
|
@@ -26,6 +27,10 @@ describe "Creating a hashed password" do
|
|
|
26
27
|
expect { BCrypt::Password.create( "" ) }.not_to raise_error
|
|
27
28
|
expect { BCrypt::Password.create( String.new ) }.not_to raise_error
|
|
28
29
|
end
|
|
30
|
+
|
|
31
|
+
specify "should tolerate very long string secrets" do
|
|
32
|
+
expect { BCrypt::Password.create("abcd"*1024) }.not_to raise_error
|
|
33
|
+
end
|
|
29
34
|
end
|
|
30
35
|
|
|
31
36
|
describe "Reading a hashed password" do
|
|
@@ -108,6 +113,7 @@ end
|
|
|
108
113
|
describe "Validating a generated salt" do
|
|
109
114
|
specify "should not accept an invalid salt" do
|
|
110
115
|
expect(BCrypt::Engine.valid_salt?("invalid")).to eq(false)
|
|
116
|
+
expect(BCrypt::Engine.valid_salt?("invalid\n#{BCrypt::Engine.generate_salt}\ninvalid")).to eq(false)
|
|
111
117
|
end
|
|
112
118
|
specify "should accept a valid salt" do
|
|
113
119
|
expect(BCrypt::Engine.valid_salt?(BCrypt::Engine.generate_salt)).to eq(true)
|
|
@@ -116,9 +122,10 @@ end
|
|
|
116
122
|
|
|
117
123
|
describe "Validating a password hash" do
|
|
118
124
|
specify "should not accept an invalid password" do
|
|
119
|
-
expect(BCrypt::Password.valid_hash?("i_am_so_not_valid")).to
|
|
125
|
+
expect(BCrypt::Password.valid_hash?("i_am_so_not_valid")).to be(false)
|
|
126
|
+
expect(BCrypt::Password.valid_hash?("invalid\n#{BCrypt::Password.create "i_am_so_valid"}\ninvalid")).to be(false)
|
|
120
127
|
end
|
|
121
128
|
specify "should accept a valid password" do
|
|
122
|
-
expect(BCrypt::Password.valid_hash?(BCrypt::Password.create "i_am_so_valid")).to
|
|
129
|
+
expect(BCrypt::Password.valid_hash?(BCrypt::Password.create "i_am_so_valid")).to be(true)
|
|
123
130
|
end
|
|
124
131
|
end
|
metadata
CHANGED
|
@@ -1,60 +1,47 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: bcrypt
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.1.
|
|
4
|
+
version: 3.1.18
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Coda Hale
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2022-05-16 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rake-compiler
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
-
- - ~>
|
|
17
|
+
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version:
|
|
19
|
+
version: 1.2.0
|
|
20
20
|
type: :development
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
|
-
- - ~>
|
|
24
|
+
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version:
|
|
26
|
+
version: 1.2.0
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: rspec
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
|
-
- -
|
|
31
|
+
- - ">="
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
33
|
version: '3'
|
|
34
34
|
type: :development
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
|
-
- -
|
|
38
|
+
- - ">="
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: '3'
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
- - ~>
|
|
46
|
-
- !ruby/object:Gem::Version
|
|
47
|
-
version: '3.12'
|
|
48
|
-
type: :development
|
|
49
|
-
prerelease: false
|
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
-
requirements:
|
|
52
|
-
- - ~>
|
|
53
|
-
- !ruby/object:Gem::Version
|
|
54
|
-
version: '3.12'
|
|
55
|
-
description: ! " bcrypt() is a sophisticated and secure hash algorithm designed
|
|
56
|
-
by The OpenBSD project\n for hashing passwords. The bcrypt Ruby gem provides
|
|
57
|
-
a simple wrapper for safely handling\n passwords.\n"
|
|
41
|
+
description: |2
|
|
42
|
+
bcrypt() is a sophisticated and secure hash algorithm designed by The OpenBSD project
|
|
43
|
+
for hashing passwords. The bcrypt Ruby gem provides a simple wrapper for safely handling
|
|
44
|
+
passwords.
|
|
58
45
|
email: coda.hale@gmail.com
|
|
59
46
|
executables: []
|
|
60
47
|
extensions:
|
|
@@ -68,26 +55,27 @@ extra_rdoc_files:
|
|
|
68
55
|
- lib/bcrypt/error.rb
|
|
69
56
|
- lib/bcrypt.rb
|
|
70
57
|
files:
|
|
71
|
-
- .
|
|
72
|
-
- .
|
|
73
|
-
- .
|
|
58
|
+
- ".github/workflows/ruby.yml"
|
|
59
|
+
- ".gitignore"
|
|
60
|
+
- ".rspec"
|
|
74
61
|
- CHANGELOG
|
|
75
62
|
- COPYING
|
|
76
63
|
- Gemfile
|
|
77
|
-
- Gemfile.lock
|
|
78
64
|
- README.md
|
|
79
65
|
- Rakefile
|
|
80
|
-
- appveyor.yml
|
|
81
66
|
- bcrypt.gemspec
|
|
82
67
|
- ext/jruby/bcrypt_jruby/BCrypt.java
|
|
83
68
|
- ext/mri/bcrypt_ext.c
|
|
84
69
|
- ext/mri/crypt.c
|
|
85
70
|
- ext/mri/crypt.h
|
|
86
71
|
- ext/mri/crypt_blowfish.c
|
|
72
|
+
- ext/mri/crypt_blowfish.h
|
|
87
73
|
- ext/mri/crypt_gensalt.c
|
|
74
|
+
- ext/mri/crypt_gensalt.h
|
|
88
75
|
- ext/mri/extconf.rb
|
|
89
76
|
- ext/mri/ow-crypt.h
|
|
90
77
|
- ext/mri/wrapper.c
|
|
78
|
+
- ext/mri/x86.S
|
|
91
79
|
- lib/bcrypt.rb
|
|
92
80
|
- lib/bcrypt/engine.rb
|
|
93
81
|
- lib/bcrypt/error.rb
|
|
@@ -97,33 +85,32 @@ files:
|
|
|
97
85
|
- spec/bcrypt/error_spec.rb
|
|
98
86
|
- spec/bcrypt/password_spec.rb
|
|
99
87
|
- spec/spec_helper.rb
|
|
100
|
-
homepage: https://github.com/
|
|
88
|
+
homepage: https://github.com/bcrypt-ruby/bcrypt-ruby
|
|
101
89
|
licenses:
|
|
102
90
|
- MIT
|
|
103
91
|
metadata: {}
|
|
104
92
|
post_install_message:
|
|
105
93
|
rdoc_options:
|
|
106
|
-
- --title
|
|
94
|
+
- "--title"
|
|
107
95
|
- bcrypt-ruby
|
|
108
|
-
- --line-numbers
|
|
109
|
-
- --inline-source
|
|
110
|
-
- --main
|
|
96
|
+
- "--line-numbers"
|
|
97
|
+
- "--inline-source"
|
|
98
|
+
- "--main"
|
|
111
99
|
- README.md
|
|
112
100
|
require_paths:
|
|
113
101
|
- lib
|
|
114
102
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
115
103
|
requirements:
|
|
116
|
-
- -
|
|
104
|
+
- - ">="
|
|
117
105
|
- !ruby/object:Gem::Version
|
|
118
106
|
version: '0'
|
|
119
107
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
120
108
|
requirements:
|
|
121
|
-
- -
|
|
109
|
+
- - ">="
|
|
122
110
|
- !ruby/object:Gem::Version
|
|
123
111
|
version: '0'
|
|
124
112
|
requirements: []
|
|
125
|
-
|
|
126
|
-
rubygems_version: 2.7.6
|
|
113
|
+
rubygems_version: 3.1.4
|
|
127
114
|
signing_key:
|
|
128
115
|
specification_version: 4
|
|
129
116
|
summary: OpenBSD's bcrypt() password hashing algorithm.
|
data/.travis.yml
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
language: ruby
|
|
2
|
-
before_install:
|
|
3
|
-
- gem update --system
|
|
4
|
-
- gem install bundler
|
|
5
|
-
rvm:
|
|
6
|
-
- 1.8
|
|
7
|
-
- 1.9
|
|
8
|
-
- 2.0
|
|
9
|
-
- 2.1
|
|
10
|
-
- 2.2
|
|
11
|
-
- 2.3
|
|
12
|
-
- 2.4
|
|
13
|
-
- 2.5
|
|
14
|
-
- 2.6
|
|
15
|
-
- ruby-head
|
|
16
|
-
- jruby-18mode
|
|
17
|
-
- jruby-19mode
|
|
18
|
-
- jruby-head
|
|
19
|
-
- rbx-3
|
|
20
|
-
- ree
|
|
21
|
-
script: bundle exec rake
|