bcrypt-ruby 2.1.4-x86-mswin32-60 → 3.0.0-x86-mswin32-60

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.
data/.gitignore CHANGED
@@ -5,3 +5,4 @@ ext/mri/Makefile
5
5
  doc
6
6
  pkg
7
7
  *.class
8
+ tmp/
data/CHANGELOG CHANGED
@@ -37,4 +37,8 @@
37
37
  - JVM 1.4/1.5 compatibility [Hongli Lai]
38
38
 
39
39
  2.1.2 Sep 16 2009
40
- - Fixed support for Solaris, OpenSolaris.
40
+ - Fixed support for Solaris, OpenSolaris.
41
+
42
+ 3.0.0 Aug 24, 2011
43
+ - Bcrypt C implementation replaced with a public domain implementation.
44
+ - License changed to MIT
data/COPYING CHANGED
@@ -1,33 +1,28 @@
1
- Copyright 2007-2009 Coda Hale <coda.hale@gmail.com>
1
+ (The MIT License)
2
2
 
3
- Original C implementation of the BCrypt algorithm by Niels Provos.
4
- jBCrypt is Copyright (c) 2006 Damien Miller <djm@mindrot.org>.
3
+ Copyright 2007-2011:
4
+
5
+ * Coda Hale <coda.hale@gmail.com>
5
6
 
6
- All rights reserved.
7
+ C implementation of the BCrypt algorithm by Solar Designer and placed in the
8
+ public domain.
9
+ jBCrypt is Copyright (c) 2006 Damien Miller <djm@mindrot.org>.
7
10
 
8
- Redistribution and use in source and binary forms, with or without
9
- modification, are permitted provided that the following conditions
10
- are met:
11
- 1. Redistributions of source code must retain the above copyright
12
- notice, this list of conditions and the following disclaimer.
13
- 2. Redistributions in binary form must reproduce the above copyright
14
- notice, this list of conditions and the following disclaimer in the
15
- documentation and/or other materials provided with the distribution.
16
- 3. All advertising materials mentioning features or use of this software
17
- must display the following acknowledgement:
11
+ Permission is hereby granted, free of charge, to any person obtaining
12
+ a copy of this software and associated documentation files (the
13
+ 'Software'), to deal in the Software without restriction, including
14
+ without limitation the rights to use, copy, modify, merge, publish,
15
+ distribute, sublicense, and/or sell copies of the Software, and to
16
+ permit persons to whom the Software is furnished to do so, subject to
17
+ the following conditions:
18
18
 
19
- This product includes software developed by Coda Hale.
20
-
21
- 4. The name of the author may not be used to endorse or promote products
22
- derived from this software without specific prior written permission.
19
+ The above copyright notice and this permission notice shall be
20
+ included in all copies or substantial portions of the Software.
23
21
 
24
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25
- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26
- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27
- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29
- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33
- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
23
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
26
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Gemfile.lock ADDED
@@ -0,0 +1,29 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ bcrypt-ruby (2.1.4)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.1.2)
10
+ rake (0.8.7)
11
+ rake-compiler (0.7.5)
12
+ rake
13
+ rspec (2.5.0)
14
+ rspec-core (~> 2.5.0)
15
+ rspec-expectations (~> 2.5.0)
16
+ rspec-mocks (~> 2.5.0)
17
+ rspec-core (2.5.1)
18
+ rspec-expectations (2.5.0)
19
+ diff-lcs (~> 1.1.2)
20
+ rspec-mocks (2.5.0)
21
+
22
+ PLATFORMS
23
+ java
24
+ ruby
25
+
26
+ DEPENDENCIES
27
+ bcrypt-ruby!
28
+ rake-compiler
29
+ rspec
data/README.md ADDED
@@ -0,0 +1,184 @@
1
+ # bcrypt-ruby
2
+
3
+ An easy way to keep your users' passwords secure.
4
+
5
+ * http://bcrypt-ruby.rubyforge.org/
6
+ * http://github.com/codahale/bcrypt-ruby/tree/master
7
+
8
+ ## Why you should use `bcrypt()`
9
+
10
+ If you store user passwords in the clear, then an attacker who steals a copy of your database has a giant list of emails
11
+ and passwords. Some of your users will only have one password -- for their email account, for their banking account, for
12
+ your application. A simple hack could escalate into massive identity theft.
13
+
14
+ It's your responsibility as a web developer to make your web application secure -- blaming your users for not being
15
+ security experts is not a professional response to risk.
16
+
17
+ `bcrypt()` allows you to easily harden your application against these kinds of attacks.
18
+
19
+ *Note*: JRuby versions of bcrypt-ruby `<= 2.1.3` had a [security
20
+ vulnerability](http://www.mindrot.org/files/jBCrypt/internat.adv) that
21
+ was fixed in `>= 2.1.4`. If you used a vulnerable version to hash
22
+ passwords with international characters in them, you will need to
23
+ re-hash those passwords. This vulernability only affected the JRuby gem.
24
+
25
+ ## How to install bcrypt
26
+
27
+ sudo gem install bcrypt-ruby
28
+
29
+ The bcrypt-ruby gem is available on the following ruby platforms:
30
+
31
+ * JRuby
32
+ * RubyInstaller 1.8 and 1.9 builds on win32
33
+ * Any 1.8 or 1.9 ruby on a BSD/OSX/Linux system with a compiler
34
+
35
+ ## How to use `bcrypt()` in your Rails application
36
+
37
+ ### The _User_ model
38
+
39
+ require 'bcrypt'
40
+
41
+ class User < ActiveRecord::Base
42
+ # users.password_hash in the database is a :string
43
+ include BCrypt
44
+
45
+ def password
46
+ @password ||= Password.new(password_hash)
47
+ end
48
+
49
+ def password=(new_password)
50
+ @password = Password.create(new_password)
51
+ self.password_hash = @password
52
+ end
53
+ end
54
+
55
+ ### Creating an account
56
+
57
+ def create
58
+ @user = User.new(params[:user])
59
+ @user.password = params[:password]
60
+ @user.save!
61
+ end
62
+
63
+ ### Authenticating a user
64
+
65
+ def login
66
+ @user = User.find_by_email(params[:email])
67
+ if @user.password == params[:password]
68
+ give_token
69
+ else
70
+ redirect_to home_url
71
+ end
72
+ end
73
+
74
+ ### If a user forgets their password?
75
+
76
+ # assign them a random one and mail it to them, asking them to change it
77
+ def forgot_password
78
+ @user = User.find_by_email(params[:email])
79
+ random_password = Array.new(10).map { (65 + rand(58)).chr }.join
80
+ @user.password = random_password
81
+ @user.save!
82
+ Mailer.create_and_deliver_password_change(@user, random_password)
83
+ end
84
+
85
+ ## How to use bcrypt-ruby in general
86
+
87
+ require 'bcrypt'
88
+
89
+ my_password = BCrypt::Password.create("my password")
90
+ #=> "$2a$10$vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa"
91
+
92
+ my_password.version #=> "2a"
93
+ my_password.cost #=> 10
94
+ my_password == "my password" #=> true
95
+ my_password == "not my password" #=> false
96
+
97
+ my_password = BCrypt::Password.new("$2a$10$vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa")
98
+ my_password == "my password" #=> true
99
+ my_password == "not my password" #=> false
100
+
101
+ Check the rdocs for more details -- BCrypt, BCrypt::Password.
102
+
103
+ ## How `bcrypt()` works
104
+
105
+ `bcrypt()` is a hashing algorithm designed by Niels Provos and David Mazières of the OpenBSD Project.
106
+
107
+ ### Background
108
+
109
+ Hash algorithms take a chunk of data (e.g., your user's password) and create a "digital fingerprint," or hash, of it.
110
+ Because this process is not reversible, there's no way to go from the hash back to the password.
111
+
112
+ In other words:
113
+
114
+ hash(p) #=> <unique gibberish>
115
+
116
+ You can store the hash and check it against a hash made of a potentially valid password:
117
+
118
+ <unique gibberish> =? hash(just_entered_password)
119
+
120
+ ### Rainbow Tables
121
+
122
+ But even this has weaknesses -- attackers can just run lists of possible passwords through the same algorithm, store the
123
+ results in a big database, and then look up the passwords by their hash:
124
+
125
+ PrecomputedPassword.find_by_hash(<unique gibberish>).password #=> "secret1"
126
+
127
+ ### Salts
128
+
129
+ The solution to this is to add a small chunk of random data -- called a salt -- to the password before it's hashed:
130
+
131
+ hash(salt + p) #=> <really unique gibberish>
132
+
133
+ The salt is then stored along with the hash in the database, and used to check potentially valid passwords:
134
+
135
+ <really unique gibberish> =? hash(salt + just_entered_password)
136
+
137
+ bcrypt-ruby automatically handles the storage and generation of these salts for you.
138
+
139
+ Adding a salt means that an attacker has to have a gigantic database for each unique salt -- for a salt made of 4
140
+ letters, that's 456,976 different databases. Pretty much no one has that much storage space, so attackers try a
141
+ different, slower method -- throw a list of potential passwords at each individual password:
142
+
143
+ hash(salt + "aadvark") =? <really unique gibberish>
144
+ hash(salt + "abacus") =? <really unique gibberish>
145
+ etc.
146
+
147
+ This is much slower than the big database approach, but most hash algorithms are pretty quick -- and therein lies the
148
+ problem. Hash algorithms aren't usually designed to be slow, they're designed to turn gigabytes of data into secure
149
+ fingerprints as quickly as possible. `bcrypt()`, though, is designed to be computationally expensive:
150
+
151
+ Ten thousand iterations:
152
+ user system total real
153
+ md5 0.070000 0.000000 0.070000 ( 0.070415)
154
+ bcrypt 22.230000 0.080000 22.310000 ( 22.493822)
155
+
156
+ If an attacker was using Ruby to check each password, they could check ~140,000 passwords a second with MD5 but only
157
+ ~450 passwords a second with `bcrypt()`.
158
+
159
+ ### Cost Factors
160
+
161
+ In addition, `bcrypt()` allows you to increase the amount of work required to hash a password as computers get faster. Old
162
+ passwords will still work fine, but new passwords can keep up with the times.
163
+
164
+ The default cost factor used by bcrypt-ruby is 10, which is fine for session-based authentication. If you are using a
165
+ stateless authentication architecture (e.g., HTTP Basic Auth), you will want to lower the cost factor to reduce your
166
+ server load and keep your request times down. This will lower the security provided you, but there are few alternatives.
167
+
168
+ ## More Information
169
+
170
+ `bcrypt()` is currently used as the default password storage hash in OpenBSD, widely regarded as the most secure operating
171
+ system available.
172
+
173
+ For a more technical explanation of the algorithm and its design criteria, please read Niels Provos and David Mazières'
174
+ Usenix99 paper:
175
+ http://www.usenix.org/events/usenix99/provos.html
176
+
177
+ If you'd like more down-to-earth advice regarding cryptography, I suggest reading <i>Practical Cryptography</i> by Niels
178
+ Ferguson and Bruce Schneier:
179
+ http://www.schneier.com/book-practical.html
180
+
181
+ # Etc
182
+
183
+ * Author :: Coda Hale <coda.hale@gmail.com>
184
+ * Website :: http://blog.codahale.com
data/Rakefile CHANGED
@@ -25,6 +25,7 @@ task :default => [:compile, :spec]
25
25
  desc "Run all specs"
26
26
  RSpec::Core::RakeTask.new do |t|
27
27
  t.pattern = 'spec/**/*_spec.rb'
28
+ t.ruby_opts = '-w'
28
29
  end
29
30
 
30
31
  desc "Run all specs, with coverage testing"
data/bcrypt-ruby.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'bcrypt-ruby'
3
- s.version = '2.1.4'
3
+ s.version = '3.0.0'
4
4
 
5
5
  s.summary = "OpenBSD's bcrypt() password hashing algorithm."
6
6
  s.description = <<-EOF
@@ -16,8 +16,8 @@ Gem::Specification.new do |s|
16
16
  s.add_development_dependency 'rspec'
17
17
 
18
18
  s.has_rdoc = true
19
- s.rdoc_options += ['--title', 'bcrypt-ruby', '--line-numbers', '--inline-source', '--main', 'README']
20
- s.extra_rdoc_files += ['README', 'COPYING', 'CHANGELOG', *Dir['lib/**/*.rb']]
19
+ s.rdoc_options += ['--title', 'bcrypt-ruby', '--line-numbers', '--inline-source', '--main', 'README.md']
20
+ s.extra_rdoc_files += ['README.md', 'COPYING', 'CHANGELOG', *Dir['lib/**/*.rb']]
21
21
 
22
22
  s.extensions = 'ext/mri/extconf.rb'
23
23
 
data/ext/mri/bcrypt_ext.c CHANGED
@@ -1,87 +1,89 @@
1
- #include "ruby.h"
2
- #include "bcrypt.h"
1
+ #include <ruby.h>
2
+ #include <ow-crypt.h>
3
3
 
4
4
  static VALUE mBCrypt;
5
5
  static VALUE cBCryptEngine;
6
6
 
7
- /* Define RSTRING_PTR for Ruby 1.8.5, ruby-core's idea of a point release is
8
- insane. */
9
- #ifndef RSTRING_PTR
10
- # define RSTRING_PTR(s) (RSTRING(s)->ptr)
11
- #endif
12
-
13
7
  #ifdef RUBY_VM
14
8
  # define RUBY_1_9
15
9
  #endif
16
10
 
17
11
  #ifdef RUBY_1_9
18
12
 
19
- /* When on Ruby 1.9+, we will want to unlock the GIL while performing
20
- * expensive calculations, for greater concurrency. Do not do this for
21
- * cheap calculations because locking/unlocking the GIL incurs some overhead as well.
22
- */
23
- #define GIL_UNLOCK_COST_THRESHOLD 9
24
-
25
- typedef struct {
26
- char *output;
27
- const char *key;
28
- const char *salt;
29
- } BCryptArguments;
30
-
31
- static VALUE bcrypt_wrapper(void *_args) {
32
- BCryptArguments *args = (BCryptArguments *)_args;
33
- return (VALUE)ruby_bcrypt(args->output, args->key, args->salt);
34
- }
13
+ /* When on Ruby 1.9+, we will want to unlock the GIL while performing
14
+ * expensive calculations, for greater concurrency. Do not do this for
15
+ * cheap calculations because locking/unlocking the GIL incurs some overhead as well.
16
+ */
17
+ #define GIL_UNLOCK_COST_THRESHOLD 9
18
+
19
+ typedef struct {
20
+ char *output;
21
+ const char *key;
22
+ const char *salt;
23
+ } BCryptArguments;
24
+
25
+ static VALUE bcrypt_wrapper(void *_args) {
26
+ BCryptArguments *args = (BCryptArguments *)_args;
27
+ return (VALUE)ruby_bcrypt(args->output, args->key, args->salt);
28
+ }
35
29
 
36
30
  #endif /* RUBY_1_9 */
37
31
 
38
32
  /* Given a logarithmic cost parameter, generates a salt for use with +bc_crypt+.
39
- */
40
- static VALUE bc_salt(VALUE self, VALUE cost, VALUE seed) {
41
- int icost = NUM2INT(cost);
42
- char salt[BCRYPT_SALT_OUTPUT_SIZE];
43
-
44
- ruby_bcrypt_gensalt(salt, icost, (uint8_t *)RSTRING_PTR(seed));
45
- return rb_str_new2(salt);
33
+ */
34
+ static VALUE bc_salt(VALUE self, VALUE prefix, VALUE count, VALUE input) {
35
+ char * salt;
36
+ VALUE str_salt;
37
+
38
+ salt = crypt_gensalt_ra(
39
+ StringValuePtr(prefix),
40
+ NUM2ULONG(count),
41
+ NIL_P(input) ? NULL : StringValuePtr(input),
42
+ NIL_P(input) ? 0 : RSTRING_LEN(input));
43
+
44
+ if(!salt) return Qnil;
45
+
46
+ str_salt = rb_str_new2(salt);
47
+ free(salt);
48
+
49
+ return str_salt;
46
50
  }
47
51
 
48
52
  /* Given a secret and a salt, generates a salted hash (which you can then store safely).
49
- */
50
- static VALUE bc_crypt(VALUE self, VALUE key, VALUE salt, VALUE cost) {
51
- const char * safeguarded = RSTRING_PTR(key) ? RSTRING_PTR(key) : "";
52
- char output[BCRYPT_OUTPUT_SIZE];
53
-
54
- #ifdef RUBY_1_9
55
- int icost = NUM2INT(cost);
56
- if (icost >= GIL_UNLOCK_COST_THRESHOLD) {
57
- BCryptArguments args;
58
- VALUE ret;
59
-
60
- args.output = output;
61
- args.key = safeguarded;
62
- args.salt = RSTRING_PTR(salt);
63
- ret = rb_thread_blocking_region(bcrypt_wrapper, &args, RUBY_UBF_IO, 0);
64
- if (ret != (VALUE) 0) {
65
- return rb_str_new2(output);
66
- } else {
67
- return Qnil;
68
- }
69
- }
70
- /* otherwise, fallback to the non-GIL-unlocking code, just like on Ruby 1.8 */
71
- #endif
72
-
73
- if (ruby_bcrypt(output, safeguarded, (char *)RSTRING_PTR(salt)) != NULL) {
74
- return rb_str_new2(output);
75
- } else {
76
- return Qnil;
77
- }
53
+ */
54
+ static VALUE bc_crypt(VALUE self, VALUE key, VALUE setting) {
55
+ char * value;
56
+ void * data;
57
+ int size;
58
+ VALUE out;
59
+
60
+ data = NULL;
61
+ size = 0xDEADBEEF;
62
+
63
+ if(NIL_P(key) || NIL_P(setting)) return Qnil;
64
+
65
+ value = crypt_ra(
66
+ NIL_P(key) ? NULL : StringValuePtr(key),
67
+ NIL_P(setting) ? NULL : StringValuePtr(setting),
68
+ &data,
69
+ &size);
70
+
71
+ if(!value) return Qnil;
72
+
73
+ out = rb_str_new(data, size - 1);
74
+
75
+ free(data);
76
+
77
+ return out;
78
78
  }
79
79
 
80
80
  /* Create the BCrypt and BCrypt::Engine modules, and populate them with methods. */
81
81
  void Init_bcrypt_ext(){
82
- mBCrypt = rb_define_module("BCrypt");
83
- cBCryptEngine = rb_define_class_under(mBCrypt, "Engine", rb_cObject);
84
-
85
- rb_define_singleton_method(cBCryptEngine, "__bc_salt", bc_salt, 2);
86
- rb_define_singleton_method(cBCryptEngine, "__bc_crypt", bc_crypt, 3);
82
+ mBCrypt = rb_define_module("BCrypt");
83
+ cBCryptEngine = rb_define_class_under(mBCrypt, "Engine", rb_cObject);
84
+
85
+ rb_define_singleton_method(cBCryptEngine, "__bc_salt", bc_salt, 3);
86
+ rb_define_singleton_method(cBCryptEngine, "__bc_crypt", bc_crypt, 2);
87
87
  }
88
+
89
+ /* vim: set noet sws=4 sw=4: */