scrypt-ruby 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/MIT-LICENSE.txt +7 -0
- data/README.md +61 -0
- data/gem-public_cert.pem +32 -0
- data/lib/scrypt-1.4.0.jar +0 -0
- data/lib/scrypt-ruby.rb +231 -0
- data/scrypt-ruby.gemspec +29 -0
- metadata +97 -0
- metadata.gz.sig +0 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0b6d46b9b645c57061fb80d42fbea4b05574550c
|
4
|
+
data.tar.gz: 200ba6e9b43d9f7a04c78e60676922ca89e6ae5b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 456336fb58d7ad005a5557850bb562e4a83cbf5936b0276a24e1857e842b8a413ff4edf1aa80e2da65b051fc2149e80b57b1f54606790463c8d1f5411bcc706a
|
7
|
+
data.tar.gz: 6f428784c04c4c55e0ad18aefe013f14971b03942003ac476a6e46743ffad5e7a04d3599ad8f7a6771a5469e7e3dd282ffaa0bc97985ecd872ab2ff6314088c0
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data.tar.gz.sig
ADDED
Binary file
|
data/MIT-LICENSE.txt
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
Copyright (c) 2016 Barry Allard barry (dot) allard (at) gmail (dot).com
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
+
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# [scrypt-ruby](https://github.com/steakknife/scrypt-ruby)
|
2
|
+
|
3
|
+
|
4
|
+
## Universal SCrypt adapter library
|
5
|
+
|
6
|
+
|
7
|
+
### Usage
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
require 'scrypt-ruby' # instead of require 'scrypt'
|
11
|
+
```
|
12
|
+
|
13
|
+
The API is basically the same as [https://github.com/pbhogan/scrypt](), so it's a drop-in replacement for scrypt on JRuby or regular Rubies
|
14
|
+
|
15
|
+
|
16
|
+
### Installation
|
17
|
+
#### Gem
|
18
|
+
```shell
|
19
|
+
gem install scrypt-ruby
|
20
|
+
```
|
21
|
+
|
22
|
+
#### Bundler
|
23
|
+
```ruby
|
24
|
+
# Gemfile
|
25
|
+
gem 'scrypt-ruby'
|
26
|
+
```
|
27
|
+
|
28
|
+
### Supported Platforms
|
29
|
+
#### JRuby
|
30
|
+
- FreeBSD
|
31
|
+
- Linux
|
32
|
+
- Mac OS X
|
33
|
+
- Windows (uncertain/untested)
|
34
|
+
|
35
|
+
Support provided by [https://github.com/wg/scrypt]()
|
36
|
+
|
37
|
+
#### MRI / CRuby / Rubinius
|
38
|
+
- FreeBSD
|
39
|
+
- Linux
|
40
|
+
- Mac OS X
|
41
|
+
- Windows
|
42
|
+
|
43
|
+
Support provided by [https://github.com/pbhogan/scrypt]()
|
44
|
+
|
45
|
+
#### Patches
|
46
|
+
|
47
|
+
PR's welcome!
|
48
|
+
|
49
|
+
For bonus points, use feature branches in your head fork to keep things clearer.
|
50
|
+
|
51
|
+
#### Issues
|
52
|
+
|
53
|
+
[Issue tracker](https://github.com/steakknife/scrypt-ruby/issues)
|
54
|
+
|
55
|
+
#### License
|
56
|
+
|
57
|
+
[MIT License](MIT-LICENSE.txt)
|
58
|
+
|
59
|
+
#### Copyright
|
60
|
+
|
61
|
+
Copyright (C) 2016 Barry Allard
|
data/gem-public_cert.pem
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
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
|
31
|
+
8m+dgfPonsYSqnDDfLuAmtKhLAA=
|
32
|
+
-----END CERTIFICATE-----
|
Binary file
|
data/lib/scrypt-ruby.rb
ADDED
@@ -0,0 +1,231 @@
|
|
1
|
+
if RUBY_ENGINE == 'jruby'
|
2
|
+
autoload :Benchmark, 'benchmark'
|
3
|
+
autoload :Digest, 'digest'
|
4
|
+
autoload :OpenSSL, 'openssl'
|
5
|
+
require File.expand_path('../scrypt-1.4.0.jar', __FILE__)
|
6
|
+
module SCrypt
|
7
|
+
@@debug = false
|
8
|
+
def self.debug=(d)
|
9
|
+
@@debug = d
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.debug(*args)
|
13
|
+
return @@debug if args.length == 0
|
14
|
+
$stderr.puts(*args) if @@debug
|
15
|
+
end
|
16
|
+
|
17
|
+
module Errors
|
18
|
+
class InvalidHash < StandardError; end
|
19
|
+
class InvalidSalt < StandardError; end
|
20
|
+
class InvalidSecret < StandardError; end
|
21
|
+
end
|
22
|
+
|
23
|
+
class Password < String
|
24
|
+
attr_reader :cost, :digest, :salt
|
25
|
+
|
26
|
+
def initialize(encrypted_password)
|
27
|
+
encrypted_password = encrypted_password.to_s
|
28
|
+
raise Errors::InvalidHash, "invalid hash" unless valid_hash? encrypted_password
|
29
|
+
@cost, @salt, @digest = split_hash(replace(encrypted_password))
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.create(plaintext_password, options = {})
|
33
|
+
options = Engine::DEFAULTS.merge(options)
|
34
|
+
key_len = [[options.delete(:key_len), 16].max, 512].min
|
35
|
+
options[:salt_size] = [[options[:salt_size], 8].max, 32].min
|
36
|
+
salt = Engine.generate_salt(options)
|
37
|
+
hash = Engine.hash_secret(plaintext_password, salt, key_len)
|
38
|
+
new(hash)
|
39
|
+
end
|
40
|
+
|
41
|
+
def ==(plaintext_password)
|
42
|
+
self.class.secure_compare(self, Engine.hash_secret(plaintext_password, @cost + @salt, self.digest.length / 2))
|
43
|
+
end
|
44
|
+
|
45
|
+
alias :is_password? :==
|
46
|
+
|
47
|
+
private
|
48
|
+
def self.secure_compare(x, y)
|
49
|
+
x.bytesize == y.bytesize && x.bytes.zip(y.bytes).inject(0) { |res, b| res |= b.inject(:^) } == 0
|
50
|
+
end
|
51
|
+
|
52
|
+
def split_hash(h)
|
53
|
+
n, v, r, salt, hash = h.to_s.split('$')
|
54
|
+
[[n, v, r].join('$') + "$", salt, hash]
|
55
|
+
end
|
56
|
+
|
57
|
+
def valid_hash?(h)
|
58
|
+
!!h.match(/^[0-9a-z]+\$[0-9a-z]+\$[0-9a-z]+\$[A-Za-z0-9]{16,64}\$[A-Za-z0-9]{32,1024}$/)
|
59
|
+
end
|
60
|
+
end # Password
|
61
|
+
|
62
|
+
class Engine
|
63
|
+
DEFAULTS = {
|
64
|
+
key_len: 32,
|
65
|
+
salt_size: 32,
|
66
|
+
max_mem: 16 * 1024 * 1024, # 16 MiB
|
67
|
+
max_memfrac: 0.5,
|
68
|
+
max_time: 0.2,
|
69
|
+
cost: nil
|
70
|
+
}
|
71
|
+
|
72
|
+
# @param plaintext_password String
|
73
|
+
# @param salt String
|
74
|
+
# @param args [String, key_len] or [n, r, p, key_len]
|
75
|
+
def self.scrypt(plaintext_password, salt, *args)
|
76
|
+
key_len = args.last
|
77
|
+
n = r = p = nil
|
78
|
+
case args.length
|
79
|
+
when 2
|
80
|
+
n, r, p = args[0].split('$').map{ |x| x.to_i(16) }
|
81
|
+
when 4
|
82
|
+
n, r, p = args
|
83
|
+
else
|
84
|
+
raise ArgumentError, 'only 4 or 6 arguments allowed'
|
85
|
+
end
|
86
|
+
raw_encrypted_password = com.lambdaworks.crypto.SCrypt.scrypt(plaintext_password.to_s.to_java_bytes, salt.to_java_bytes, n, r, p, key_len)
|
87
|
+
String.from_java_bytes raw_encrypted_password
|
88
|
+
end
|
89
|
+
|
90
|
+
# "4000$8$4$c6d101522d3cb045"
|
91
|
+
def self.generate_salt(options = {})
|
92
|
+
options = DEFAULTS.merge(options)
|
93
|
+
cost = options[:cost] || calibrate(options)
|
94
|
+
salt_size = options.delete :salt_size
|
95
|
+
salt = OpenSSL::Random.random_bytes(salt_size).unpack('H*').first.rjust(16,'0')
|
96
|
+
if salt.length == 40
|
97
|
+
#If salt is 40 characters, the regexp will think that it is an old-style hash, so add a '0'.
|
98
|
+
salt = '0' + salt
|
99
|
+
end
|
100
|
+
cost + salt
|
101
|
+
end
|
102
|
+
|
103
|
+
# N r p
|
104
|
+
# "4000$8$4$"
|
105
|
+
def self.calibrate!(options = {})
|
106
|
+
DEFAULTS[:cost] = calibrate(options)
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.debug(*args)
|
110
|
+
SCrypt.debug(*args)
|
111
|
+
end
|
112
|
+
|
113
|
+
# N r p
|
114
|
+
# "400$8$25$"
|
115
|
+
def self.calibrate(options = {})
|
116
|
+
options = DEFAULTS.merge(options)
|
117
|
+
max_mem = options.delete :max_mem
|
118
|
+
max_memfrac = options.delete :max_memfrac
|
119
|
+
max_time = options.delete :max_time
|
120
|
+
|
121
|
+
mem_limit = memtouse(max_mem, max_memfrac)
|
122
|
+
ops_limit = [cpuperf * max_time, 32768].min
|
123
|
+
debug "ops_limit #{ops_limit} ops"
|
124
|
+
|
125
|
+
n, r, p = nil, 8, nil
|
126
|
+
|
127
|
+
if ops_limit < mem_limit/32
|
128
|
+
debug "pick based on CPU limit"
|
129
|
+
# Set p = 1 and choose N based on the CPU limit.
|
130
|
+
p = 1
|
131
|
+
max_n = ops_limit / (r * 4)
|
132
|
+
n = 1 << (1...63).find { |i| (1 << i) > max_n / 2 }
|
133
|
+
else
|
134
|
+
debug "pick based on memory limit"
|
135
|
+
# Set N based on the memory limit. */
|
136
|
+
max_n = mem_limit / (r * 128)
|
137
|
+
n = 1 << (1..63).find { |i| (1 << i) > max_n / 2 }
|
138
|
+
|
139
|
+
# Choose p based on the CPU limit. */
|
140
|
+
max_rp = [(ops_limit / 4) / (1 << n), 0x3fffffff].min
|
141
|
+
p = max_rp / r
|
142
|
+
end
|
143
|
+
debug "calibrated using: N #{n} r #{r} p #{p}"
|
144
|
+
"#{n.to_s(16)}$#{r.to_s(16)}$#{p.to_s(16)}$"
|
145
|
+
end
|
146
|
+
|
147
|
+
# @returns Boolean
|
148
|
+
def self.valid_cost?(cost)
|
149
|
+
!!cost.match(/^[0-9a-z]+\$[0-9a-z]+\$[0-9a-z]+\$$/)
|
150
|
+
end
|
151
|
+
|
152
|
+
# @returns Boolean
|
153
|
+
def self.valid_salt?(salt)
|
154
|
+
!!salt.match(/^[0-9a-z]+\$[0-9a-z]+\$[0-9a-z]+\$[A-Za-z0-9]{16,64}$/)
|
155
|
+
end
|
156
|
+
|
157
|
+
# @returns Boolean
|
158
|
+
def self.valid_secret?(secret)
|
159
|
+
secret.respond_to?(:to_s)
|
160
|
+
end
|
161
|
+
|
162
|
+
def self.hash_secret_old(secret, salt, cost)
|
163
|
+
salt + "$" + Digest::SHA1.hexdigest(scrypt(secret.to_s, salt, cost, 256))
|
164
|
+
end
|
165
|
+
|
166
|
+
def self.hash_secret_new(secret, salt_only, cost, key_len)
|
167
|
+
salt_only = [salt_only.sub(/^(00)+/, '')].pack('H*')
|
168
|
+
scrypt(secret.to_s, salt_only, cost, key_len).unpack('H*').first.rjust(key_len * 2, '0')
|
169
|
+
end
|
170
|
+
|
171
|
+
# "400$8$26$b62e0f787a5fc373$0399ccd4fa26642d92741b17c366b7f6bd12ccea5214987af445d2bed97bc6a2"
|
172
|
+
def self.hash_secret(secret, salt, key_len = DEFAULTS[:key_len])
|
173
|
+
raise Errors::InvalidSalt, "invalid salt" unless valid_salt? salt
|
174
|
+
raise Errors::InvalidSecret, "invalid secret" unless valid_secret? secret
|
175
|
+
|
176
|
+
cost = cost_from_salt(salt)
|
177
|
+
salt_only = salt_only(salt)
|
178
|
+
|
179
|
+
if salt_only.length == 40
|
180
|
+
hash_secret_old(secret, salt, cost)
|
181
|
+
else
|
182
|
+
salt + "$" + hash_secret_new(secret, salt_only, cost, key_len)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
private
|
187
|
+
|
188
|
+
def self.cost_from_salt(salt)
|
189
|
+
salt[/^[0-9a-z]+\$[0-9a-z]+\$[0-9a-z]+\$/]
|
190
|
+
end
|
191
|
+
|
192
|
+
def self.salt_only(salt)
|
193
|
+
salt[/\$([A-Za-z0-9]{16,64})$/, 1]
|
194
|
+
end
|
195
|
+
|
196
|
+
# Estimate how many scrypts / second
|
197
|
+
def self.cpuperf
|
198
|
+
iterations = 1000
|
199
|
+
empty_array = "".to_java_bytes.freeze
|
200
|
+
run = -> { iterations.times { com.lambdaworks.crypto.SCrypt.scrypt(empty_array, empty_array, 128, 1, 1, 1) } }
|
201
|
+
# warm-up
|
202
|
+
run.()
|
203
|
+
loop do
|
204
|
+
time = Benchmark.realtime { |x| run.() }
|
205
|
+
if time > 0.33
|
206
|
+
per_sec = iterations/time
|
207
|
+
debug "cpuperf #{per_sec} ops/s"
|
208
|
+
return per_sec
|
209
|
+
end
|
210
|
+
iterations *= 10
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
#
|
215
|
+
def self.memtouse(max_mem, max_memfrac)
|
216
|
+
max_memfrac = 0.5 if max_memfrac > 0.5 || max_memfrac == 0
|
217
|
+
|
218
|
+
memlimit_min = java.lang.Runtime.getRuntime.freeMemory
|
219
|
+
debug "free mem #{memlimit_min / 1048576} MiB"
|
220
|
+
|
221
|
+
mem_avail = max_memfrac * memlimit_min
|
222
|
+
mem_avail = [mem_avail, max_mem].min if max_mem > 0
|
223
|
+
mem_avail = [mem_avail, 1024*1024].max
|
224
|
+
debug "memtouse #{mem_avail / 1048576} MiB"
|
225
|
+
mem_avail
|
226
|
+
end
|
227
|
+
end # Engine
|
228
|
+
end # SCrypt
|
229
|
+
else
|
230
|
+
require 'scrypt'
|
231
|
+
end
|
data/scrypt-ruby.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
Gem::Specification::new do |s|
|
2
|
+
s.name = 'scrypt-ruby'
|
3
|
+
s.version = '2.0.0'
|
4
|
+
s.summary = 'Universal SCrypt adapter'
|
5
|
+
s.description = 'Universal SCrypt PBKDF adapter (for CRuby (MRI) and JRuby)'
|
6
|
+
s.license = 'MIT'
|
7
|
+
|
8
|
+
s.files = [
|
9
|
+
'README.md',
|
10
|
+
'MIT-LICENSE.txt',
|
11
|
+
'gem-public_cert.pem',
|
12
|
+
'scrypt-ruby.gemspec',
|
13
|
+
'lib/scrypt-1.4.0.jar',
|
14
|
+
'lib/scrypt-ruby.rb',
|
15
|
+
]
|
16
|
+
|
17
|
+
s.required_ruby_version = '>= 1.9.3'
|
18
|
+
s.require_path = 'lib'
|
19
|
+
s.author = 'Barry Allard'
|
20
|
+
s.email = 'barry.allard@gmail.com'
|
21
|
+
s.homepage = 'https://github.com/steakknife/scrypt-ruby'
|
22
|
+
|
23
|
+
if RUBY_PLATFORM == 'java'
|
24
|
+
s.platform = 'java'
|
25
|
+
else
|
26
|
+
s.add_dependency 'scrypt', '~> 2.0'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
.tap {|gem| pk = File.expand_path(File.join('~/.keys', 'gem-private_key.pem')); gem.signing_key = pk if File.exist? pk; gem.cert_chain = ['gem-public_cert.pem']} # pressed firmly by waxseal
|
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: scrypt-ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Barry Allard
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain:
|
11
|
+
- |
|
12
|
+
-----BEGIN CERTIFICATE-----
|
13
|
+
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
|
42
|
+
8m+dgfPonsYSqnDDfLuAmtKhLAA=
|
43
|
+
-----END CERTIFICATE-----
|
44
|
+
date: 2016-03-14 00:00:00.000000000 Z
|
45
|
+
dependencies:
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: scrypt
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - "~>"
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '2.0'
|
53
|
+
type: :runtime
|
54
|
+
prerelease: false
|
55
|
+
version_requirements: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - "~>"
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '2.0'
|
60
|
+
description: Universal SCrypt PBKDF adapter (for CRuby (MRI) and JRuby)
|
61
|
+
email: barry.allard@gmail.com
|
62
|
+
executables: []
|
63
|
+
extensions: []
|
64
|
+
extra_rdoc_files: []
|
65
|
+
files:
|
66
|
+
- MIT-LICENSE.txt
|
67
|
+
- README.md
|
68
|
+
- gem-public_cert.pem
|
69
|
+
- lib/scrypt-1.4.0.jar
|
70
|
+
- lib/scrypt-ruby.rb
|
71
|
+
- scrypt-ruby.gemspec
|
72
|
+
homepage: https://github.com/steakknife/scrypt-ruby
|
73
|
+
licenses:
|
74
|
+
- MIT
|
75
|
+
metadata: {}
|
76
|
+
post_install_message:
|
77
|
+
rdoc_options: []
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: 1.9.3
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
requirements: []
|
91
|
+
rubyforge_project:
|
92
|
+
rubygems_version: 2.6.1
|
93
|
+
signing_key:
|
94
|
+
specification_version: 4
|
95
|
+
summary: Universal SCrypt adapter
|
96
|
+
test_files: []
|
97
|
+
has_rdoc:
|
metadata.gz.sig
ADDED
Binary file
|