argon2id 0.4.0-arm64-darwin → 0.5.0-arm64-darwin
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 +4 -4
- data/CHANGELOG.md +19 -1
- data/README.md +17 -14
- data/argon2id.gemspec +1 -1
- data/lib/3.1/argon2id.bundle +0 -0
- data/lib/3.2/argon2id.bundle +0 -0
- data/lib/3.3/argon2id.bundle +0 -0
- data/lib/argon2id/password.rb +7 -12
- data/lib/argon2id/version.rb +1 -1
- data/lib/argon2id.rb +31 -28
- data/test/test_hash_encoded.rb +6 -0
- data/test/test_password.rb +12 -12
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dd8fb6e7a98af48e2a557b6fc59ca84cc0ace08cb4b37284a8fef84ec17536a3
|
4
|
+
data.tar.gz: a5b6e47350cd443ac0c45eb1af1813e8f8b2034cf8af8e29de58bf8fc1719c2c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0c773a4b232c172bf7e2c7a9ae165d43df0de90196ffd9060cb10c060c1f5e74957bf6624e67851b1273e4f913e980c2f91ea43965ade17ccc279ad1c19e79c7
|
7
|
+
data.tar.gz: 72a120dd8c2a34ee86898cc78b8538bc1a15e44921bfdb543c1ff0e92d7e8f448048276084d5a51518539702de7a9d7ae5dda11da7cfd68da28d463fb2ece840
|
data/CHANGELOG.md
CHANGED
@@ -5,12 +5,28 @@ All notable changes to this project will be documented in this file.
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
7
|
|
8
|
+
## [0.5.0] - 2024-11-02
|
9
|
+
|
10
|
+
### Removed
|
11
|
+
|
12
|
+
- No longer expose the `type` of an encoded hash as it must always be an
|
13
|
+
Argon2id hash
|
14
|
+
|
15
|
+
## [0.4.1] - 2024-11-02
|
16
|
+
|
17
|
+
### Changed
|
18
|
+
|
19
|
+
- Refactor verification on JRuby to avoid parsing encoded hashes unnecessarily
|
20
|
+
- No longer describe the gem in terms of bindings to the reference C
|
21
|
+
implementation given the Bouncy Castle-based JRuby implementation
|
22
|
+
- Only wrap `IllegalStateException` with `Argon2id::Error` on JRuby
|
23
|
+
|
8
24
|
## [0.4.0] - 2024-11-02
|
9
25
|
|
10
26
|
### Added
|
11
27
|
|
12
28
|
- Added support for JRuby 9.4 by adding an implementation of Argon2id hashing
|
13
|
-
and verification using JRuby-OpenSSL's Bouncy Castle internals
|
29
|
+
and verification using JRuby-OpenSSL's Bouncy Castle internals
|
14
30
|
- Added `output` to `Argon2id::Password` instances so the actual "output" part
|
15
31
|
of a password hash can be retrieved (and compared)
|
16
32
|
|
@@ -77,6 +93,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
77
93
|
reference C implementation of Argon2, the password-hashing function that won
|
78
94
|
the Password Hashing Competition.
|
79
95
|
|
96
|
+
[0.5.0]: https://github.com/mudge/argon2id/releases/tag/v0.5.0
|
97
|
+
[0.4.1]: https://github.com/mudge/argon2id/releases/tag/v0.4.1
|
80
98
|
[0.4.0]: https://github.com/mudge/argon2id/releases/tag/v0.4.0
|
81
99
|
[0.3.0]: https://github.com/mudge/argon2id/releases/tag/v0.3.0
|
82
100
|
[0.2.1]: https://github.com/mudge/argon2id/releases/tag/v0.2.1
|
data/README.md
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# Argon2id - Ruby bindings to the OWASP recommended password-hashing function
|
2
2
|
|
3
|
-
Ruby bindings to
|
4
|
-
|
3
|
+
Ruby bindings to [Argon2][], the password-hashing function that won the 2015
|
4
|
+
[Password Hashing Competition][].
|
5
5
|
|
6
6
|
[](https://github.com/mudge/argon2id/actions)
|
7
7
|
|
8
|
-
**Current version:** 0.
|
8
|
+
**Current version:** 0.5.0
|
9
9
|
**Bundled Argon2 version:** libargon2.1 (20190702)
|
10
10
|
|
11
11
|
```ruby
|
@@ -127,7 +127,7 @@ password == "opensesame" #=> true
|
|
127
127
|
password == "notopensesame" #=> false
|
128
128
|
```
|
129
129
|
|
130
|
-
Or, if you only have the hash (e.g. retrieved from storage):
|
130
|
+
Or, if you only have the encoded hash (e.g. retrieved from storage):
|
131
131
|
|
132
132
|
```ruby
|
133
133
|
password = Argon2id::Password.new("$argon2id$v=19$m=19456,t=2,p=1$ZS2nBFWBpnt28HjtzNOW4w$SQ+p+dIcWbpzWpZQ/ZZFj8IQkyhYZf127U4QdkRmKFU")
|
@@ -135,6 +135,10 @@ password == "opensesame" #=> true
|
|
135
135
|
password == "notopensesame" #=> false
|
136
136
|
```
|
137
137
|
|
138
|
+
> [!WARNING]
|
139
|
+
> `Argon2id::Password.new` does not support hashes generated from other Argon2
|
140
|
+
> variants such as Argon2i and Argon2d.
|
141
|
+
|
138
142
|
For compatibility with [bcrypt-ruby][], `Argon2id::Password#==` is aliased to `Argon2id::Password.is_password?`:
|
139
143
|
|
140
144
|
```ruby
|
@@ -143,11 +147,10 @@ password.is_password?("opensesame") #=> true
|
|
143
147
|
password.is_password?("notopensesame") #=> false
|
144
148
|
```
|
145
149
|
|
146
|
-
The various parts of the encoded
|
150
|
+
The various parts of the encoded hash can be retrieved:
|
147
151
|
|
148
152
|
```ruby
|
149
153
|
password = Argon2id::Password.new("$argon2id$v=19$m=256,t=2,p=1$c29tZXNhbHQ$nf65EOgLrQMR/uIPnA4rEsF5h7TKyQwu9U1bMCHGi/4")
|
150
|
-
password.type #=> "argon2id"
|
151
154
|
password.version #=> 19
|
152
155
|
password.m_cost #=> 256
|
153
156
|
password.t_cost #=> 2
|
@@ -177,7 +180,7 @@ This gem requires any of the following to run:
|
|
177
180
|
> [!NOTE]
|
178
181
|
> The JRuby version of the gem uses
|
179
182
|
> [JRuby-OpenSSL](https://github.com/jruby/jruby-openssl)'s implementation of
|
180
|
-
> Argon2
|
183
|
+
> Argon2 while the others use the reference C implementation.
|
181
184
|
|
182
185
|
### Native gems
|
183
186
|
|
@@ -198,11 +201,11 @@ notes](https://github.com/mudge/argon2id/releases) for each version and can be
|
|
198
201
|
checked with `sha256sum`, e.g.
|
199
202
|
|
200
203
|
```console
|
201
|
-
$ gem fetch argon2id -v 0.
|
202
|
-
Fetching argon2id-0.
|
203
|
-
Downloaded argon2id-0.
|
204
|
-
$ sha256sum argon2id-0.
|
205
|
-
|
204
|
+
$ gem fetch argon2id -v 0.4.1
|
205
|
+
Fetching argon2id-0.4.1-arm64-darwin.gem
|
206
|
+
Downloaded argon2id-0.4.1-arm64-darwin
|
207
|
+
$ sha256sum argon2id-0.4.1-arm64-darwin.gem
|
208
|
+
c74c06c2c4ce70d6c3822f05d83bab4ea431dd16ec086c9c856da3c6e0d9bbe9 argon2id-0.4.1-arm64-darwin.gem
|
206
209
|
```
|
207
210
|
|
208
211
|
[GPG](https://www.gnupg.org/) signatures are attached to each release (the
|
@@ -212,8 +215,8 @@ from a public keyserver, e.g. `gpg --keyserver keyserver.ubuntu.com --recv-key
|
|
212
215
|
0x39AC3530070E0F75`):
|
213
216
|
|
214
217
|
```console
|
215
|
-
$ gpg --verify argon2id-0.
|
216
|
-
gpg: Signature made
|
218
|
+
$ gpg --verify argon2id-0.4.1-arm64-darwin.gem.sig argon2id-0.4.1-arm64-darwin.gem
|
219
|
+
gpg: Signature made Sat 2 Nov 20:50:54 2024 GMT
|
217
220
|
gpg: using RSA key 702609D9C790F45B577D7BEC39AC3530070E0F75
|
218
221
|
gpg: Good signature from "Paul Mucur <mudge@mudge.name>" [unknown]
|
219
222
|
gpg: aka "Paul Mucur <paul@ghostcassette.com>" [unknown]
|
data/argon2id.gemspec
CHANGED
@@ -6,7 +6,7 @@ Gem::Specification.new do |s|
|
|
6
6
|
s.name = "argon2id"
|
7
7
|
s.version = Argon2id::VERSION
|
8
8
|
s.summary = "Ruby bindings to Argon2"
|
9
|
-
s.description = "Ruby bindings to
|
9
|
+
s.description = "Ruby bindings to Argon2, the password-hashing function that won the 2015 Password Hashing Competition."
|
10
10
|
s.license = "BSD-3-Clause"
|
11
11
|
s.authors = ["Paul Mucur"]
|
12
12
|
s.homepage = "https://github.com/mudge/argon2id"
|
data/lib/3.1/argon2id.bundle
CHANGED
Binary file
|
data/lib/3.2/argon2id.bundle
CHANGED
Binary file
|
data/lib/3.3/argon2id.bundle
CHANGED
Binary file
|
data/lib/argon2id/password.rb
CHANGED
@@ -25,7 +25,6 @@ module Argon2id
|
|
25
25
|
#
|
26
26
|
# You can read various parameters out of a password hash:
|
27
27
|
#
|
28
|
-
# password.type #=> "argon2id"
|
29
28
|
# password.version #=> 19
|
30
29
|
# password.m_cost #=> 19456
|
31
30
|
# password.t_cost #=> 2
|
@@ -36,7 +35,7 @@ module Argon2id
|
|
36
35
|
PATTERN = %r{
|
37
36
|
\A
|
38
37
|
\$
|
39
|
-
|
38
|
+
argon2id
|
40
39
|
(?:\$v=(\d+))?
|
41
40
|
\$m=(\d+)
|
42
41
|
,t=(\d+)
|
@@ -51,9 +50,6 @@ module Argon2id
|
|
51
50
|
# The encoded password hash.
|
52
51
|
attr_reader :encoded
|
53
52
|
|
54
|
-
# The type of the hashing function.
|
55
|
-
attr_reader :type
|
56
|
-
|
57
53
|
# The version number of the hashing function.
|
58
54
|
attr_reader :version
|
59
55
|
|
@@ -113,13 +109,12 @@ module Argon2id
|
|
113
109
|
raise ArgumentError, "invalid hash" unless PATTERN =~ String(encoded)
|
114
110
|
|
115
111
|
@encoded = $&
|
116
|
-
@
|
117
|
-
@
|
118
|
-
@
|
119
|
-
@
|
120
|
-
@
|
121
|
-
@
|
122
|
-
@output = $7.unpack1("m")
|
112
|
+
@version = Integer($1 || 0x10)
|
113
|
+
@m_cost = Integer($2)
|
114
|
+
@t_cost = Integer($3)
|
115
|
+
@parallelism = Integer($4)
|
116
|
+
@salt = $5.unpack1("m")
|
117
|
+
@output = $6.unpack1("m")
|
123
118
|
end
|
124
119
|
|
125
120
|
# Return the encoded password hash.
|
data/lib/argon2id/version.rb
CHANGED
data/lib/argon2id.rb
CHANGED
@@ -57,7 +57,35 @@ module Argon2id
|
|
57
57
|
Error = Class.new(StandardError)
|
58
58
|
|
59
59
|
def self.hash_encoded(t_cost, m_cost, parallelism, pwd, salt, hashlen)
|
60
|
-
|
60
|
+
output = hash_raw(t_cost, m_cost, parallelism, pwd, salt, hashlen)
|
61
|
+
|
62
|
+
encoder = Java::JavaUtil::Base64.get_encoder.without_padding
|
63
|
+
encoded_salt = encoder.encode_to_string(salt.to_java_bytes)
|
64
|
+
encoded_output = encoder.encode_to_string(output)
|
65
|
+
|
66
|
+
"$argon2id$v=19$m=#{Integer(m_cost)},t=#{Integer(t_cost)}," \
|
67
|
+
"p=#{Integer(parallelism)}$#{encoded_salt}$#{encoded_output}"
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.verify(encoded, pwd)
|
71
|
+
password = Password.new(encoded)
|
72
|
+
other_raw = hash_raw(
|
73
|
+
password.t_cost,
|
74
|
+
password.m_cost,
|
75
|
+
password.parallelism,
|
76
|
+
String(pwd),
|
77
|
+
password.salt,
|
78
|
+
password.output.bytesize
|
79
|
+
)
|
80
|
+
|
81
|
+
Java::OrgBouncycastleUtil::Arrays.constant_time_are_equal(
|
82
|
+
password.output.to_java_bytes,
|
83
|
+
other_raw
|
84
|
+
)
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.hash_raw(t_cost, m_cost, parallelism, pwd, salt, hashlen)
|
88
|
+
raise Error, "Salt is too short" if String(salt).empty?
|
61
89
|
|
62
90
|
hash = Java::byte[Integer(hashlen)].new
|
63
91
|
params = Java::OrgBouncycastleCryptoParams::Argon2Parameters::Builder
|
@@ -68,38 +96,13 @@ module Argon2id
|
|
68
96
|
.with_iterations(Integer(t_cost))
|
69
97
|
.build
|
70
98
|
generator = Java::OrgBouncycastleCryptoGenerators::Argon2BytesGenerator.new
|
71
|
-
encoder = Java::JavaUtil::Base64.get_encoder.without_padding
|
72
99
|
|
73
100
|
generator.init(params)
|
74
101
|
generator.generate_bytes(String(pwd).to_java_bytes, hash)
|
75
102
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
"$argon2id$v=#{params.get_version}$m=#{params.get_memory}," \
|
80
|
-
"t=#{params.get_iterations},p=#{params.get_lanes}" \
|
81
|
-
"$#{encoded_salt}$#{encoded_output}"
|
82
|
-
rescue => e
|
103
|
+
hash
|
104
|
+
rescue Java::JavaLang::IllegalStateException => e
|
83
105
|
raise Error, e.message
|
84
106
|
end
|
85
|
-
|
86
|
-
def self.verify(encoded, pwd)
|
87
|
-
password = Password.new(encoded)
|
88
|
-
other_password = Password.new(
|
89
|
-
hash_encoded(
|
90
|
-
password.t_cost,
|
91
|
-
password.m_cost,
|
92
|
-
password.parallelism,
|
93
|
-
String(pwd),
|
94
|
-
password.salt,
|
95
|
-
password.output.bytesize
|
96
|
-
)
|
97
|
-
)
|
98
|
-
|
99
|
-
Java::OrgBouncycastleUtil::Arrays.constant_time_are_equal(
|
100
|
-
password.output.to_java_bytes,
|
101
|
-
other_password.output.to_java_bytes
|
102
|
-
)
|
103
|
-
end
|
104
107
|
end
|
105
108
|
end
|
data/test/test_hash_encoded.rb
CHANGED
@@ -10,6 +10,12 @@ class TestHashEncoded < Minitest::Test
|
|
10
10
|
assert_equal "$argon2id$v=19$m=256,t=2,p=1$c29tZXNhbHQ$nf65EOgLrQMR/uIPnA4rEsF5h7TKyQwu9U1bMCHGi/4", encoded
|
11
11
|
end
|
12
12
|
|
13
|
+
def test_password_with_parallelism_of_two
|
14
|
+
encoded = Argon2id.hash_encoded(2, 256, 2, "password", "somesalt", 32)
|
15
|
+
|
16
|
+
assert_equal "$argon2id$v=19$m=256,t=2,p=2$c29tZXNhbHQ$bQk8UB/VmZZF4Oo79iDXuL5/0ttZwg2f/5U52iv1cDc", encoded
|
17
|
+
end
|
18
|
+
|
13
19
|
def test_valid_password_does_not_include_trailing_null_byte
|
14
20
|
encoded = Argon2id.hash_encoded(2, 256, 1, "password", "somesalt", 32)
|
15
21
|
|
data/test/test_password.rb
CHANGED
@@ -98,6 +98,12 @@ class TestPassword < Minitest::Test
|
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
101
|
+
def test_raises_for_non_argon2id_hashes
|
102
|
+
assert_raises(ArgumentError) do
|
103
|
+
Argon2id::Password.new("$argon2i$v=19$m=256,t=2,p=1$c29tZXNhbHQ$iekCn0Y3spW+sCcFanM2xBT63UP2sghkUoHLIUpWRS8")
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
101
107
|
def test_salt_supports_versionless_hashes
|
102
108
|
password = Argon2id::Password.new("$argon2id$m=256,t=2,p=1$c29tZXNhbHQ$nf65EOgLrQMR/uIPnA4rEsF5h7TKyQwu9U1bMCHGi/4")
|
103
109
|
|
@@ -110,18 +116,6 @@ class TestPassword < Minitest::Test
|
|
110
116
|
assert Argon2id::Password.new(password) == "password"
|
111
117
|
end
|
112
118
|
|
113
|
-
def test_extracting_type_from_hash
|
114
|
-
password = Argon2id::Password.new("$argon2id$v=19$m=256,t=2,p=1$c29tZXNhbHQ$nf65EOgLrQMR/uIPnA4rEsF5h7TKyQwu9U1bMCHGi/4")
|
115
|
-
|
116
|
-
assert_equal "argon2id", password.type
|
117
|
-
end
|
118
|
-
|
119
|
-
def test_extracting_type_from_argoni_hash
|
120
|
-
password = Argon2id::Password.new("$argon2i$v=19$m=256,t=2,p=1$c29tZXNhbHQ$nf65EOgLrQMR/uIPnA4rEsF5h7TKyQwu9U1bMCHGi/4")
|
121
|
-
|
122
|
-
assert_equal "argon2i", password.type
|
123
|
-
end
|
124
|
-
|
125
119
|
def test_extracting_version_from_hash
|
126
120
|
password = Argon2id::Password.new("$argon2id$v=19$m=256,t=2,p=1$c29tZXNhbHQ$nf65EOgLrQMR/uIPnA4rEsF5h7TKyQwu9U1bMCHGi/4")
|
127
121
|
|
@@ -169,4 +163,10 @@ class TestPassword < Minitest::Test
|
|
169
163
|
|
170
164
|
assert_equal 1, password.parallelism
|
171
165
|
end
|
166
|
+
|
167
|
+
def test_extracting_output_from_hash
|
168
|
+
password = Argon2id::Password.new("$argon2id$v=19$m=256,t=2,p=1$c29tZXNhbHQ$nf65EOgLrQMR/uIPnA4rEsF5h7TKyQwu9U1bMCHGi/4")
|
169
|
+
|
170
|
+
assert_equal "\x9D\xFE\xB9\x10\xE8\v\xAD\x03\x11\xFE\xE2\x0F\x9C\x0E+\x12\xC1y\x87\xB4\xCA\xC9\f.\xF5M[0!\xC6\x8B\xFE".b, password.output
|
171
|
+
end
|
172
172
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: argon2id
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: arm64-darwin
|
6
6
|
authors:
|
7
7
|
- Paul Mucur
|
@@ -52,8 +52,8 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '5.25'
|
55
|
-
description: Ruby bindings to the
|
56
|
-
|
55
|
+
description: Ruby bindings to Argon2, the password-hashing function that won the 2015
|
56
|
+
Password Hashing Competition.
|
57
57
|
email:
|
58
58
|
executables: []
|
59
59
|
extensions: []
|