crypt_checkpass 1
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/.gitignore +32 -0
- data/.rubocop.yml +96 -0
- data/.yardopts +5 -0
- data/Gemfile +41 -0
- data/LICENSE.txt +19 -0
- data/README.md +114 -0
- data/Rakefile +46 -0
- data/bin/console +29 -0
- data/bin/setup +24 -0
- data/crypt_checkpass.gemspec +55 -0
- data/lib/crypt_checkpass.rb +75 -0
- data/lib/crypt_checkpass/api.rb +212 -0
- data/lib/crypt_checkpass/argon2.rb +204 -0
- data/lib/crypt_checkpass/bcrypt.rb +217 -0
- data/lib/crypt_checkpass/pbkdf2.rb +177 -0
- data/lib/crypt_checkpass/phc_string_format.rb +180 -0
- data/lib/crypt_checkpass/scrypt.rb +214 -0
- data/lib/crypt_checkpass/sha2.rb +162 -0
- metadata +201 -0
@@ -0,0 +1,214 @@
|
|
1
|
+
#! /your/favourite/path/to/ruby
|
2
|
+
# -*- mode: ruby; coding: utf-8; indent-tabs-mode: nil; ruby-indent-level: 2 -*-
|
3
|
+
# -*- frozen_string_literal: true -*-
|
4
|
+
# -*- warn_indent: true -*-
|
5
|
+
|
6
|
+
# Copyright (c) 2018 Urabe, Shyouhei
|
7
|
+
#
|
8
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
9
|
+
# of this software and associated documentation files (the "Software"), to deal
|
10
|
+
# in the Software without restriction, including without limitation the rights
|
11
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
12
|
+
# copies of the Software, and to permit persons to whom the Software is
|
13
|
+
# furnished to do so, subject to the following conditions:
|
14
|
+
#
|
15
|
+
# The above copyright notice and this permission notice shall be
|
16
|
+
# included in all copies or substantial portions of the Software.
|
17
|
+
#
|
18
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
21
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
22
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
23
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
24
|
+
# SOFTWARE.
|
25
|
+
|
26
|
+
require 'securerandom'
|
27
|
+
require_relative 'phc_string_format'
|
28
|
+
|
29
|
+
# This class is to support RFC7914-related hash variants.
|
30
|
+
#
|
31
|
+
# ### Format:
|
32
|
+
#
|
33
|
+
# Life gets extremely hard here because Ruby's `scrypt` gem does not follow the
|
34
|
+
# Modular Crypt Format. You cannot tell if a string is scrypt-generated or not
|
35
|
+
# by looking at its beginning.
|
36
|
+
#
|
37
|
+
# ```ruby
|
38
|
+
# %r{
|
39
|
+
# (?<N> [0-9a-f]+ ){0}
|
40
|
+
# (?<r> [0-9a-f]+ ){0}
|
41
|
+
# (?<p> [0-9a-f]+ ){0}
|
42
|
+
# (?<salt> [0-9a-f]+ ){0}
|
43
|
+
# (?<csum> [0-9a-f]+ ){0}
|
44
|
+
#
|
45
|
+
# \A \g<N>
|
46
|
+
# [$] \g<r>
|
47
|
+
# [$] \g<p>
|
48
|
+
# [$] \g<salt>
|
49
|
+
# [$] \g<csum>
|
50
|
+
# \z
|
51
|
+
# }x
|
52
|
+
# ```
|
53
|
+
#
|
54
|
+
# - `N` is the CPU/Memory cost parameter N ("costParameter").
|
55
|
+
#
|
56
|
+
# - `r` is the block size parameter r ("blockSize").
|
57
|
+
#
|
58
|
+
# - `p` is the parallelization parameter p ("parallelizationParameter").
|
59
|
+
#
|
60
|
+
# - `salt` is the salt string.
|
61
|
+
#
|
62
|
+
# - `csum` is the checksum strgng.
|
63
|
+
#
|
64
|
+
# All of above fields are represented as hexadecimal numbers.
|
65
|
+
#
|
66
|
+
# This is too different from other password hashs. To ease the situation we
|
67
|
+
# also follow extra format that is compatible with Python's Passlib and npm's
|
68
|
+
# @phc/scrypt generates.
|
69
|
+
#
|
70
|
+
# ```ruby
|
71
|
+
# %r{
|
72
|
+
# (?<id> scrypt ){0}
|
73
|
+
# (?<ln> ln=[1-9][0-9]* ){0}
|
74
|
+
# (?<r> r=[1-9][0-9]* ){0}
|
75
|
+
# (?<p> p=[1-9][0-9]* ){0}
|
76
|
+
# (?<salt> [a-zA-Z0-9+/]* ){0}
|
77
|
+
# (?<csum> [a-zA-Z0-9+/]* ){0}
|
78
|
+
#
|
79
|
+
# \A [$] \g<id>
|
80
|
+
# [$] \g<ln>
|
81
|
+
# [,] \g<r>
|
82
|
+
# [,] \g<p>
|
83
|
+
# [$] \g<salt>
|
84
|
+
# [$] \g<csum>
|
85
|
+
# \z
|
86
|
+
# }x
|
87
|
+
# ```
|
88
|
+
#
|
89
|
+
# - This is a strict PHC string format. See also
|
90
|
+
# {CryptCheckpass::PHCStringFormat}
|
91
|
+
#
|
92
|
+
# - Parameters are `ln`, `r`, and `p` where `ln` deontes log2(N).
|
93
|
+
#
|
94
|
+
# ### Other formats:
|
95
|
+
#
|
96
|
+
# Seems there are no such thing like a standard way to encode scrypt-generated
|
97
|
+
# passwords. Lots of wild formats are seen. We could support them if they
|
98
|
+
# have actual usage and to be migrated to another format.
|
99
|
+
#
|
100
|
+
# - variant `$7$`: seem in http://mail.tarsnap.com/scrypt/msg00063.html. Not
|
101
|
+
# sure if it has actual applications.
|
102
|
+
#
|
103
|
+
# - variant `$s1$`: https://github.com/technion/libscrypt generates this.
|
104
|
+
#
|
105
|
+
# - variant `$$scrypt-mcf$`: the default output of https://libpasta.github.io
|
106
|
+
#
|
107
|
+
# - Recent OpenSSL (1.1.0+) does have EVP_PBE_scrypt() implemented, but
|
108
|
+
# generates pure-binary raw checksums without any formats.
|
109
|
+
#
|
110
|
+
# @see https://en.wikipedia.org/wiki/Scrypt
|
111
|
+
# @see https://tools.ietf.org/html/rfc7914
|
112
|
+
# @see https://blog.ircmaxell.com/2014/03/why-i-dont-recommend-scrypt.html
|
113
|
+
# @example
|
114
|
+
# crypt_newhash 'password', id: 'scrypt'
|
115
|
+
# # => "$scrypt$ln=8,r=8,p=1$aL2uvFKrfoVkxAgy1j/Y4OAJ8D0p1yP/uqFg3UU8t64$/xZGQyALLQrKzaBRGwzGCw+FGgRqFwyCfZddC5qvZYA"
|
116
|
+
# @example
|
117
|
+
# crypt_checkpass? 'password', '$scrypt$ln=8,r=8,p=1$aL2uvFKrfoVkxAgy1j/Y4OAJ8D0p1yP/uqFg3UU8t64$/xZGQyALLQrKzaBRGwzGCw+FGgRqFwyCfZddC5qvZYA'
|
118
|
+
# # => true
|
119
|
+
|
120
|
+
class CryptCheckpass::Scrypt < CryptCheckpass
|
121
|
+
|
122
|
+
# (see CryptCheckpass.understand?)
|
123
|
+
def self.understand? str
|
124
|
+
return match? str, understander
|
125
|
+
end
|
126
|
+
|
127
|
+
# (see CryptCheckpass.checkpass?)
|
128
|
+
def self.checkpass? pass, hash
|
129
|
+
require 'scrypt'
|
130
|
+
|
131
|
+
case hash
|
132
|
+
when /\A\$scrypt\$/ then return checkpass_phc pass, hash
|
133
|
+
else return checkpass_gem pass, hash
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
# (see CryptCheckpass.provide?)
|
138
|
+
def self.provide? id
|
139
|
+
return id == 'scrypt'
|
140
|
+
end
|
141
|
+
|
142
|
+
# (see CryptCheckpass.newhash)
|
143
|
+
#
|
144
|
+
# @param pass [String] raw binary password string.
|
145
|
+
# @param id [String] name of the algorithm (ignored)
|
146
|
+
# @param ln [Integer] cost parameter in log2.
|
147
|
+
# @param r [Integer] block size.
|
148
|
+
# @param p [Integer] parallelism parameter.
|
149
|
+
def self.newhash pass, id: 'scrypt', ln: 8, r: 8, p: 1
|
150
|
+
require 'scrypt'
|
151
|
+
|
152
|
+
salt = SecureRandom.random_bytes ::SCrypt::Engine::DEFAULTS[:salt_size]
|
153
|
+
klen = ::SCrypt::Engine::DEFAULTS[:key_len]
|
154
|
+
csum = ::SCrypt::Engine.scrypt pass, salt, 2 ** ln, r, p, klen
|
155
|
+
return phcencode 'scrypt', { ln: ln, r: r, p: p }, salt, csum
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# helper routines
|
160
|
+
class << CryptCheckpass::Scrypt
|
161
|
+
include CryptCheckpass::PHCStringFormat
|
162
|
+
|
163
|
+
private
|
164
|
+
|
165
|
+
def checkpass_phc pass, hash
|
166
|
+
require 'consttime_memequal'
|
167
|
+
|
168
|
+
json = phcdecode hash
|
169
|
+
ln, r, p = json[:params].values_at :ln, :r, :p
|
170
|
+
expected = json[:csum]
|
171
|
+
salt = json[:salt]
|
172
|
+
klen = ::SCrypt::Engine::DEFAULTS[:key_len]
|
173
|
+
actual = ::SCrypt::Engine.scrypt pass, salt, 2 ** ln, r, p, klen
|
174
|
+
return consttime_memequal? actual, expected
|
175
|
+
end
|
176
|
+
|
177
|
+
def checkpass_gem pass, hash
|
178
|
+
obj = ::SCrypt::Password.new hash
|
179
|
+
return obj == pass
|
180
|
+
end
|
181
|
+
|
182
|
+
def understander
|
183
|
+
return %r{
|
184
|
+
(?<n1> [0-9a-f]+ ){0}
|
185
|
+
(?<r1> [0-9a-f]+ ){0}
|
186
|
+
(?<p1> [0-9a-f]+ ){0}
|
187
|
+
(?<salt1> [0-9a-f]+ ){0}
|
188
|
+
(?<csum1> [0-9a-f]+ ){0}
|
189
|
+
|
190
|
+
(?<id2> scrypt ){0}
|
191
|
+
(?<ln2> ln=[1-9][0-9]* ){0}
|
192
|
+
(?<r2> r=[1-9][0-9]* ){0}
|
193
|
+
(?<p2> p=[1-9][0-9]* ){0}
|
194
|
+
(?<salt2> [a-zA-Z0-9+/]* ){0}
|
195
|
+
(?<csum2> [a-zA-Z0-9+/]* ){0}
|
196
|
+
|
197
|
+
\A (?:
|
198
|
+
\g<n1>
|
199
|
+
[$] \g<r1>
|
200
|
+
[$] \g<p1>
|
201
|
+
[$] \g<salt1>
|
202
|
+
[$] \g<csum1>
|
203
|
+
|
204
|
+
|
|
205
|
+
[$] \g<id2>
|
206
|
+
[$] \g<ln2>
|
207
|
+
[,] \g<r2>
|
208
|
+
[,] \g<p2>
|
209
|
+
[$] \g<salt2>
|
210
|
+
[$] \g<csum2>
|
211
|
+
) \z
|
212
|
+
}x
|
213
|
+
end
|
214
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
#! /your/favourite/path/to/ruby
|
2
|
+
# -*- mode: ruby; coding: utf-8; indent-tabs-mode: nil; ruby-indent-level: 2 -*-
|
3
|
+
# -*- frozen_string_literal: true -*-
|
4
|
+
# -*- warn_indent: true -*-
|
5
|
+
|
6
|
+
# Copyright (c) 2018 Urabe, Shyouhei
|
7
|
+
#
|
8
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
9
|
+
# of this software and associated documentation files (the "Software"), to deal
|
10
|
+
# in the Software without restriction, including without limitation the rights
|
11
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
12
|
+
# copies of the Software, and to permit persons to whom the Software is
|
13
|
+
# furnished to do so, subject to the following conditions:
|
14
|
+
#
|
15
|
+
# The above copyright notice and this permission notice shall be
|
16
|
+
# included in all copies or substantial portions of the Software.
|
17
|
+
#
|
18
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
21
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
22
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
23
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
24
|
+
# SOFTWARE.
|
25
|
+
|
26
|
+
# The sha256cyrpt / sha512crypt by Ulrich Drepper. Default for `/etc/shadow`
|
27
|
+
# of most Linux distributions. Also no security flaws are known at the moment.
|
28
|
+
#
|
29
|
+
# ### Newhash:
|
30
|
+
#
|
31
|
+
# You can use `crypto_newhash` to create a new password hash using SHA2:
|
32
|
+
#
|
33
|
+
# ```ruby
|
34
|
+
# crypt_newhash(password, id: 'sha256', rounds: 1024)
|
35
|
+
# ```
|
36
|
+
#
|
37
|
+
# where:
|
38
|
+
#
|
39
|
+
# - `password` is the raw binary password that you want to digest.
|
40
|
+
#
|
41
|
+
# - `id` is either "sha256" or "sha512".
|
42
|
+
#
|
43
|
+
# - `rounds` is for iteration rounds.
|
44
|
+
#
|
45
|
+
# The generated password hash has following format.
|
46
|
+
#
|
47
|
+
# ### Format:
|
48
|
+
#
|
49
|
+
# Hash strings generated by sha256cyrpt is construted like this:
|
50
|
+
#
|
51
|
+
# ```ruby
|
52
|
+
# %r{
|
53
|
+
# (?<id> 5 ){0}
|
54
|
+
# (?<rounds> rounds=[1-9]\d{3,8} ){0}
|
55
|
+
# (?<salt> [A-Za-z0-9./]{,16} ){0}
|
56
|
+
# (?<csum> [A-Za-z0-9./]{43} ){0}
|
57
|
+
#
|
58
|
+
# \A [$] \g<id>
|
59
|
+
# (?: [$] \g<rounds> )?
|
60
|
+
# [$] \g<salt>
|
61
|
+
# [$] \g<csum>
|
62
|
+
# \z
|
63
|
+
# }x
|
64
|
+
# ```
|
65
|
+
#
|
66
|
+
# That of sha512crypt is construted like this:
|
67
|
+
#
|
68
|
+
# ```ruby
|
69
|
+
# %r{
|
70
|
+
# (?<id> 6 ){0}
|
71
|
+
# (?<rounds> rounds=[1-9]\d{3,8} ){0}
|
72
|
+
# (?<salt> [A-Za-z0-9./]{,16} ){0}
|
73
|
+
# (?<csum> [A-Za-z0-9./]{86} ){0}
|
74
|
+
#
|
75
|
+
# \A [$] \g<id>
|
76
|
+
# (?: [$] \g<rounds> )?
|
77
|
+
# [$] \g<salt>
|
78
|
+
# [$] \g<csum>
|
79
|
+
# \z
|
80
|
+
# }x
|
81
|
+
# ```
|
82
|
+
#
|
83
|
+
# - `id` is 5 for sha256cyrpt, 6 for sha512crypt.
|
84
|
+
#
|
85
|
+
# - `rounds` is, if present, the stretch rounds in decimal integer. Should be
|
86
|
+
# in range of 1,000 to 999,999,999 inclusive.
|
87
|
+
#
|
88
|
+
# - `salt` and `csum` are the salt and checksum strings. Both are encoded in
|
89
|
+
# base64-like strings that do not strictly follow RFC4648. The only
|
90
|
+
# difference between `$5$` and `$6$` is the length of csum.
|
91
|
+
#
|
92
|
+
# @see https://www.akkadia.org/drepper/SHA-crypt.txt
|
93
|
+
# @example
|
94
|
+
# crypt_newhash 'password', id: 'sha256'
|
95
|
+
# # => "$5$eWGIDuRO1LEg8sAB$Pjdxj3AVy4GnFfeOfz8Ek1Gn.vDwTFMMyNk56x/lc.4"
|
96
|
+
# @example
|
97
|
+
# crypt_checkpass? 'password', '$5$eWGIDuRO1LEg8sAB$Pjdxj3AVy4GnFfeOfz8Ek1Gn.vDwTFMMyNk56x/lc.4'
|
98
|
+
# # => true
|
99
|
+
# @example
|
100
|
+
# crypt_newhash 'password', id: 'sha512'
|
101
|
+
# # => "$6$oIlkXbDGlU.HktGx$L7xkRSQYLe/yCbz6hIM2JSY6EMtkr/CyvR71Bhr9VkotfEOUiwY8A0rAuSFmO1titWLA8hTKQXWl3ZX0QqokS0"
|
102
|
+
# @example
|
103
|
+
# crypt_checkpass? 'password', '$6$oIlkXbDGlU.HktGx$L7xkRSQYLe/yCbz6hIM2JSY6EMtkr/CyvR71Bhr9VkotfEOUiwY8A0rAuSFmO1titWLA8hTKQXWl3ZX0QqokS0'
|
104
|
+
# # => true
|
105
|
+
class CryptCheckpass::SHA2 < CryptCheckpass
|
106
|
+
|
107
|
+
# (see CryptCheckpass.understand?)
|
108
|
+
def self.understand? str
|
109
|
+
md = %r{
|
110
|
+
(?<id> 5 | 6 ){0}
|
111
|
+
(?<rounds> rounds=[1-9]\d{3,8} ){0}
|
112
|
+
(?<salt> [A-Za-z0-9./]{,16} ){0}
|
113
|
+
(?<csum> [A-Za-z0-9./]{43,86} ){0}
|
114
|
+
|
115
|
+
\A [$] \g<id>
|
116
|
+
(?: [$] \g<rounds> )?
|
117
|
+
[$] \g<salt>
|
118
|
+
[$] \g<csum>
|
119
|
+
\z
|
120
|
+
}x.match str
|
121
|
+
return false unless md
|
122
|
+
case md['id']
|
123
|
+
when '5' then return md['csum'].length == 43
|
124
|
+
when '6' then return md['csum'].length == 86
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# (see CryptCheckpass.checkpass?)
|
129
|
+
def self.checkpass? pass, hash
|
130
|
+
require 'unix-crypt', 'unix_crypt'
|
131
|
+
|
132
|
+
return UnixCrypt.valid? pass, hash
|
133
|
+
end
|
134
|
+
|
135
|
+
# (see CryptCheckpass.provide?)
|
136
|
+
def self.provide? id
|
137
|
+
case id when 'sha256', 'sha512' then
|
138
|
+
return true
|
139
|
+
else
|
140
|
+
return false
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# (see CryptCheckpass.newhash)
|
145
|
+
#
|
146
|
+
# @param pass [String] raw binary password string.
|
147
|
+
# @param id [String] name of the algorithm.
|
148
|
+
# @param rounds [Integer] rounds of stretching.
|
149
|
+
def self.newhash pass, id: 'sha256', rounds: nil
|
150
|
+
require 'unix-crypt', 'unix_crypt'
|
151
|
+
|
152
|
+
case id
|
153
|
+
when 'sha256' then
|
154
|
+
klass = UnixCrypt::SHA256
|
155
|
+
when 'sha512' then
|
156
|
+
klass = UnixCrypt::SHA512
|
157
|
+
else
|
158
|
+
raise ArgumentError, 'unknown id: %p', id
|
159
|
+
end
|
160
|
+
return klass.build pass, nil, rounds
|
161
|
+
end
|
162
|
+
end
|
metadata
ADDED
@@ -0,0 +1,201 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: crypt_checkpass
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '1'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Urabe, Shyouhei
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-06-25 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pry-byebug
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rdoc
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: redcarpet
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.49.0
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.49.0
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: simplecov
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: test-unit
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '3'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '3'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: yard
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: consttime_memequal
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
description: Check password hash, like OpenBSD's crypt_checkpass(3) / PHP's password_verify()
|
154
|
+
email: shyouhei@ruby-lang.org
|
155
|
+
executables: []
|
156
|
+
extensions: []
|
157
|
+
extra_rdoc_files: []
|
158
|
+
files:
|
159
|
+
- ".gitignore"
|
160
|
+
- ".rubocop.yml"
|
161
|
+
- ".yardopts"
|
162
|
+
- Gemfile
|
163
|
+
- LICENSE.txt
|
164
|
+
- README.md
|
165
|
+
- Rakefile
|
166
|
+
- bin/console
|
167
|
+
- bin/setup
|
168
|
+
- crypt_checkpass.gemspec
|
169
|
+
- lib/crypt_checkpass.rb
|
170
|
+
- lib/crypt_checkpass/api.rb
|
171
|
+
- lib/crypt_checkpass/argon2.rb
|
172
|
+
- lib/crypt_checkpass/bcrypt.rb
|
173
|
+
- lib/crypt_checkpass/pbkdf2.rb
|
174
|
+
- lib/crypt_checkpass/phc_string_format.rb
|
175
|
+
- lib/crypt_checkpass/scrypt.rb
|
176
|
+
- lib/crypt_checkpass/sha2.rb
|
177
|
+
homepage: https://github.com/shyouhei/crypt_checkpass
|
178
|
+
licenses:
|
179
|
+
- MIT
|
180
|
+
metadata: {}
|
181
|
+
post_install_message:
|
182
|
+
rdoc_options: []
|
183
|
+
require_paths:
|
184
|
+
- lib
|
185
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
186
|
+
requirements:
|
187
|
+
- - ">="
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: 2.0.0
|
190
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - ">="
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '0'
|
195
|
+
requirements: []
|
196
|
+
rubyforge_project:
|
197
|
+
rubygems_version: 2.5.2.2
|
198
|
+
signing_key:
|
199
|
+
specification_version: 4
|
200
|
+
summary: provides crypt_checkpass / crypt_newhash
|
201
|
+
test_files: []
|