enzoic 1.1.3 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 193cc6ee5e5585ea3a76add970ce69feb44c2383
4
- data.tar.gz: a77cdcf48592e05a9f06ef1ad486467002f2df30
2
+ SHA256:
3
+ metadata.gz: 2af7917c4ee90414cdffeda3948ce2a0642f523f6c44fe07db64deab4f5b6e25
4
+ data.tar.gz: 4cdfeb61e75c47f95132e9a0c644f89a987597a48685038ac7308dba66e008ee
5
5
  SHA512:
6
- metadata.gz: 641ca919dd26147fe4e06550923f380f2b54eb0959372171f57a4f17ff2bcd5f98adcd446d3d39e9f0205910671307c7e78b6954ffa77e0ad58513f25ca31084
7
- data.tar.gz: 9acf2c9d120dc0292f136b7583ba0d36f2aacd4c7e9fe52de19ec2c6468f7f42738e939250893345fe1fdc6e5d77b44e203db2558b34b0a541303365515b393d
6
+ metadata.gz: 557fadc6dab20d5d76d2098466c31728ecba0a1fcd16ce9cd13a798817239bb791012691b37130b7e64dd7275728d83c9f89bdfeda10dbde0b369faf705f8ecf
7
+ data.tar.gz: 420af16ed93a7696969a74fbfcd13e491e23f934a9f15712fe42fc3eb777e6cdcf51751ac4ebc2bfa28b250fc7d17c3107f10989a524c4f1779811254423cc50
data/README.md CHANGED
@@ -35,6 +35,7 @@ require 'enzoic'
35
35
  enzoic = Enzoic::Enzoic.new(apiKey: YOUR_API_KEY, secret: YOUR_API_SECRET)
36
36
 
37
37
  # Check whether a password has been compromised
38
+ # see https://www.enzoic.com/docs-passwords-api/ for more information
38
39
  if enzoic.check_password("password-to-test")
39
40
  puts("Password is compromised")
40
41
  else
@@ -42,6 +43,7 @@ else
42
43
  end
43
44
 
44
45
  # Check whether a specific set of credentials are compromised
46
+ # see https://www.enzoic.com/docs-credentials-api/ for more information
45
47
  if enzoic.check_credentials("test@enzoic.com", "password-to-test")
46
48
  puts("Credentials are compromised")
47
49
  else
@@ -53,7 +55,7 @@ end
53
55
  # lastCheckDate is the timestamp for the last check you performed for this user.
54
56
  # If the DateTime you provide for the last check is greater than the timestamp Enzoic has
55
57
  # for the last breach affecting this user, the check will not be performed.
56
- # This can be used to substantially increase performance.
58
+ # This can be used to substantially increase performance.
57
59
  if enzoic.check_credentials("test@enzoic.com", "password-to-test", DateTime.parse("2019-07-15T19:57:43.000Z"))
58
60
  puts("Credentials are compromised")
59
61
  else
@@ -61,12 +63,20 @@ else
61
63
  end
62
64
 
63
65
  # get all exposures for a given user
66
+ # see https://www.enzoic.com/docs-exposures-api/#get-exposures for more information
64
67
  exposures = enzoic.get_exposures_for_user("test@enzoic.com")
65
68
  puts(exposures.count.to_s + " exposures found for test@enzoic.com")
66
69
 
67
70
  # now get the full details for the first exposure found
71
+ # see https://www.enzoic.com/docs-exposures-api/#get-exposure-details for more information
68
72
  details = enzoic.get_exposure_details(exposures.exposures[0])
69
73
  puts("First exposure for test@enzoic.com was " + details.title)
74
+
75
+ # get all passwords for a given user - requires special approval, contact Enzoic sales
76
+ # see https://www.enzoic.com/docs-raw-passwords-api/ for more information
77
+ user_passwords = enzoic.get_passwords_for_user("eicar_0@enzoic.com")
78
+ puts("First password for eicar_0@enzoic.com was " + user_passwords.passwords[0].password)
79
+
70
80
  ```
71
81
 
72
82
  More information in reference format can be found below.
data/Rakefile CHANGED
@@ -20,9 +20,9 @@ Rake::ExtensionTask.new('whirlpool', gemspec) do |ext|
20
20
  ext.lib_dir = 'lib/digest'
21
21
  end
22
22
 
23
- # Rake::ExtensionTask.new('argon2-wrapper', gemspec) do |ext|
24
- # ext.ext_dir = 'ext/argon2-wrapper'
25
- # ext.lib_dir = 'lib/enzoic'
26
- # end
23
+ Rake::ExtensionTask.new('argon2-wrapper', gemspec) do |ext|
24
+ ext.ext_dir = 'ext/argon2-wrapper'
25
+ ext.lib_dir = 'lib/enzoic'
26
+ end
27
27
 
28
28
  task :default => :test
data/enzoic.gemspec CHANGED
@@ -27,7 +27,7 @@ Gem::Specification.new do |spec|
27
27
  spec.add_dependency 'unix-crypt', '~> 1.3'
28
28
  spec.add_dependency 'base64url', '~> 1.0', '>= 1.0.1'
29
29
 
30
- spec.add_development_dependency "bundler", '~> 2.0.2', '>= 2.0.2'
30
+ spec.add_development_dependency "bundler", '~> 2.2.11', '>= 2.2.11'
31
31
  spec.add_development_dependency "rake", '~> 10.4', '>= 10.4.2'
32
32
  spec.add_development_dependency "test-unit", '~> 3.2', '>= 3.2.4'
33
33
  spec.add_development_dependency "rake-compiler", '~> 1.0', '>= 1.0.4'
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -24,6 +24,14 @@ module Enzoic
24
24
  return Digest::SHA1.hexdigest to_hash
25
25
  end
26
26
 
27
+ def self.sha1_binary(to_hash)
28
+ return Digest::SHA1.digest(to_hash).bytes
29
+ end
30
+
31
+ def self.sha1_binary_array(to_hash_bytes)
32
+ return Digest::SHA1.digest(to_hash_bytes.pack('c*')).bytes
33
+ end
34
+
27
35
  def self.sha256(to_hash)
28
36
  return Digest::SHA256.hexdigest to_hash
29
37
  end
@@ -91,7 +99,7 @@ module Enzoic
91
99
 
92
100
  itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
93
101
  to_hash_bytes = to_hash.bytes
94
- count = 2**itoa64.index(salt[3])
102
+ count = 2 ** itoa64.index(salt[3])
95
103
  justsalt = salt[4..12]
96
104
 
97
105
  hash = self.md5_binary(justsalt + to_hash)
@@ -148,13 +156,146 @@ module Enzoic
148
156
  end
149
157
 
150
158
  def self.md5crypt(to_hash, salt)
151
- return UnixCrypt::MD5.build(to_hash, salt.start_with?("$1$") ? salt[3..salt.length] : salt);
159
+ return UnixCrypt::MD5.build(to_hash, salt.start_with?("$1$") ? salt[3..salt.length] : salt)
152
160
  end
153
161
 
154
162
  def self.custom_algorithm4(to_hash, salt)
155
163
  return self.bcrypt(self.md5(to_hash), salt)
156
164
  end
157
165
 
166
+ def self.custom_algorithm5(to_hash, salt)
167
+ return self.sha256(self.md5(to_hash + salt))
168
+ end
169
+
170
+ def self.osCommerce_AEF(to_hash, salt)
171
+ return self.md5(salt + to_hash)
172
+ end
173
+
174
+ def self.desCrypt(to_hash, salt)
175
+ return UnixCrypt::DES.build(to_hash, salt)
176
+ end
177
+
178
+ def self.convertToUnsigned(val)
179
+ return [val].pack('L').unpack('L').first
180
+ end
181
+
182
+ def self.mySQLPre4_1(to_hash)
183
+ nr = 1345345333
184
+ add = 7
185
+ nr2 = 0x12345671
186
+
187
+ for i in 0..to_hash.length - 1 do
188
+ c = to_hash[i]
189
+
190
+ if c == " " || c == "\t"
191
+ next
192
+ end
193
+
194
+ tmp = c.ord
195
+ nr = nr ^ ((((nr & 63) + add) * tmp) + (self.convertToUnsigned(nr << 8)))
196
+ nr2 += (self.convertToUnsigned(nr2 << 8)) ^ nr
197
+ add += tmp
198
+ end
199
+
200
+ result1 = nr & ((self.convertToUnsigned(1 << 31)) - 1)
201
+ result2 = nr2 & ((self.convertToUnsigned(1 << 31)) - 1)
202
+
203
+ return result1.to_s(16) + result2.to_s(16)
204
+ end
205
+
206
+ def self.mySQLPost4_1(to_hash)
207
+ return "*" + self.bytes_to_hex(self.sha1_binary_array(self.sha1_binary(to_hash)));
208
+ end
209
+
210
+ def self.punBB(to_hash, salt)
211
+ return self.sha1(salt + self.sha1(to_hash))
212
+ end
213
+
214
+ def self.custom_algorithm6(to_hash, salt)
215
+ return self.sha1(to_hash + salt)
216
+ end
217
+
218
+ def self.partial_md5_20(to_hash)
219
+ return self.md5(to_hash)[0..19]
220
+ end
221
+
222
+ def self.partial_md5_29(to_hash)
223
+ return self.md5(to_hash)[0..28]
224
+ end
225
+
226
+ def self.ave_datalife_diferior(to_hash)
227
+ return self.md5(self.md5(to_hash))
228
+ end
229
+
230
+ def self.django_md5(to_hash, salt)
231
+ return "md5$" + salt + "$" + self.md5(salt + to_hash)
232
+ end
233
+
234
+ def self.django_sha1(to_hash, salt)
235
+ return "sha1$" + salt + "$" + self.sha1(salt + to_hash)
236
+ end
237
+
238
+ def self.pligg_cms(to_hash, salt)
239
+ return salt + self.sha1(salt + to_hash)
240
+ end
241
+
242
+ def self.runcms_smf1_1(to_hash, salt)
243
+ return self.sha1(salt + to_hash)
244
+ end
245
+
246
+ def self.ntlm(to_hash)
247
+ pwd = to_hash.dup
248
+ pwd = pwd.dup.force_encoding('UTF-8').encode(Encoding::UTF_16LE, Encoding::UTF_8).force_encoding('UTF-8')
249
+ OpenSSL::Digest::MD4.hexdigest pwd
250
+ end
251
+
252
+ def self.sha1dash(to_hash, salt)
253
+ return self.sha1("--" + salt + "--" + to_hash + "--")
254
+ end
255
+
256
+ def self.sha384(to_hash)
257
+ return Digest::SHA384.hexdigest to_hash
258
+ end
259
+
260
+ def self.custom_algorithm7(to_hash, salt)
261
+ derived_salt = self.sha1(salt)
262
+ return OpenSSL::HMAC.hexdigest("SHA256",
263
+ "d2e1a4c569e7018cc142e9cce755a964bd9b193d2d31f02d80bb589c959afd7e",
264
+ derived_salt + to_hash)
265
+ end
266
+
267
+ def self.custom_algorithm9(to_hash, salt)
268
+ result = self.sha512(to_hash + salt)
269
+ for i in 0..10 do
270
+ result = self.sha512(result)
271
+ end
272
+ return result
273
+ end
274
+
275
+ def self.sha512crypt(to_hash, salt)
276
+ return UnixCrypt::SHA512.build(to_hash, salt.start_with?("$6$") ? salt[3..salt.length] : salt)
277
+ end
278
+
279
+ def self.custom_algorithm10(to_hash, salt)
280
+ return self.sha512(to_hash + ":" + salt)
281
+ end
282
+
283
+ def self.sha256crypt(to_hash, salt)
284
+ salt_to_use = salt
285
+ if salt_to_use.start_with?("$5$")
286
+ salt_to_use = salt_to_use[3..salt.length];
287
+ end
288
+ if salt_to_use.start_with?("rounds=")
289
+ salt_to_use = salt_to_use[salt_to_use.index("$") + 1..salt_to_use.length]
290
+ end
291
+
292
+ return UnixCrypt::SHA256.build(to_hash, salt_to_use)
293
+ end
294
+
295
+ def self.authMeSHA256(to_hash, salt)
296
+ return "$SHA$" + salt + "$" + self.sha256(self.sha256(to_hash) + salt);
297
+ end
298
+
158
299
  def self.argon2_raw(to_hash, salt)
159
300
  time_cost = 3
160
301
  mem_cost = 10
@@ -238,13 +379,13 @@ module Enzoic
238
379
  end
239
380
 
240
381
  def self.xor(byte_array1, byte_array2)
241
- result = Array.new(byte_array1.length);
382
+ result = Array.new(byte_array1.length);
242
383
 
243
- for i in 0..byte_array1.length - 1 do
244
- result[i] = byte_array1[i] ^ byte_array2[i];
245
- end
384
+ for i in 0..byte_array1.length - 1 do
385
+ result[i] = byte_array1[i] ^ byte_array2[i];
386
+ end
246
387
 
247
- return result;
388
+ return result;
248
389
  end
249
390
 
250
391
  def self.bytes_to_hex(bytes)
@@ -18,6 +18,32 @@ module Enzoic
18
18
  SHA512 = 14
19
19
  MD5Crypt = 16
20
20
  CustomAlgorithm4 = 17
21
+ CustomAlgorithm5 = 18
22
+ OsCommerce_AEF = 19
23
+ DESCrypt = 20
24
+ MySQLPre4_1 = 21
25
+ MySQLPost4_1 = 22
26
+ PeopleSoft = 23
27
+ PunBB = 24
28
+ CustomAlgorithm6 = 25
29
+ PartialMD5_20 = 26
30
+ AVE_DataLife_Diferior = 27
31
+ DjangoMD5 = 28
32
+ DjangoSHA1 = 29
33
+ PartialMD5_29 = 30
34
+ PliggCMS = 31
35
+ RunCMS_SMF1_1 = 32
36
+ NTLM = 33
37
+ SHA1Dash = 34
38
+ SHA384 = 35
39
+ CustomAlgorithm7 = 36
40
+ CustomAlgorithm8 = 37
41
+ CustomAlgorithm9 = 38
42
+ SHA512Crypt = 39
43
+ CustomAlgorithm10 = 40
44
+ SHA256Crypt = 41
45
+ AuthMeSHA256 = 42
46
+
21
47
  Unknown = 97
22
48
  UnusablePassword = 98
23
49
  None = 99
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  # Standard Gem version constant.
3
3
  module Enzoic
4
- VERSION = "1.1.3".freeze
4
+ VERSION = "1.2.0".freeze
5
5
  end
data/lib/enzoic.rb CHANGED
@@ -15,61 +15,72 @@ module Enzoic
15
15
  # to access the Enzoic API.
16
16
  class Enzoic
17
17
  def initialize(options = {})
18
- @apiKey = options[:apiKey] || '';
18
+ @apiKey = options[:apiKey] || ''
19
19
  raise EnzoicFail, "No API key provided" if @apiKey == ''
20
- @secret = options[:secret] || '';
20
+ @secret = options[:secret] || ''
21
21
  raise EnzoicFail, "No Secret provided" if @secret == ''
22
22
  @baseURL = options[:baseURL] || "https://api.enzoic.com/v1"
23
23
  @authString = calc_auth_string(@apiKey, @secret)
24
24
  end
25
25
 
26
- def check_credentials(username, password, lastCheckTimestamp = Date.new(1980, 1, 1))
26
+ def check_credentials(username, password, last_check_timestamp = Date.new(1980, 1, 1))
27
27
  raise EnzoicFail, "API key/Secret not set" if !@authString || @authString == ''
28
28
 
29
- response = make_rest_call(@baseURL + Constants::ACCOUNTS_API_PATH + "?username=" + Hashing.sha256(username), "GET", nil)
29
+ response = make_rest_call(@baseURL + Constants::ACCOUNTS_API_PATH +
30
+ "?username=" + Hashing.sha256(username.downcase),
31
+ "GET", nil)
30
32
 
31
- if (response == "404")
33
+ if response == "404"
32
34
  return false
33
35
  end
34
36
 
35
37
  account_response = JSON.parse(response)
36
38
 
37
39
  # if lastCheckTimestamp was provided, see if we need to go any further
38
- if (Date.parse(account_response["lastBreachDate"]) > lastCheckTimestamp)
40
+ if Date.parse(account_response["lastBreachDate"]) > last_check_timestamp
39
41
  hashes_required = account_response["passwordHashesRequired"]
40
42
 
41
43
  bcrypt_count = 0
42
44
  query_string = ""
45
+ credential_hashes = []
43
46
 
44
- for i in 0..hashes_required.length - 1 do
45
- hash_spec = hashes_required[i]
46
-
47
+ hashes_required.each do |hash_spec|
47
48
  # bcrypt gets far too expensive for good response time if there are many of them to calculate.
48
49
  # some mostly garbage accounts have accumulated a number of them in our DB and if we happen to hit one it
49
50
  # kills performance, so short circuit out after at most 2 BCrypt hashes
50
- if (hash_spec["hashType"] != PasswordType::BCrypt || bcrypt_count <= 2)
51
- if (hash_spec["hashType"] == PasswordType::BCrypt)
51
+ if hash_spec["hashType"] != PasswordType::BCrypt || bcrypt_count <= 2
52
+ if hash_spec["hashType"] == PasswordType::BCrypt
52
53
  bcrypt_count = bcrypt_count + 1
53
54
  end
54
55
 
55
- if (hash_spec["hashType"] != nil)
56
- credential_hash = calc_credential_hash(username, password, account_response["salt"], hash_spec);
56
+ if hash_spec["hashType"] != nil
57
+ credential_hash = calc_credential_hash(username.downcase, password, account_response["salt"], hash_spec)
58
+
59
+ if credential_hash != nil
60
+ credential_hashes << credential_hash
57
61
 
58
- if (credential_hash != nil)
59
- if (query_string.length == 0)
60
- query_string = query_string + "?hashes=" + CGI.escape(credential_hash);
62
+ if query_string.length == 0
63
+ query_string = query_string + "?partialHashes=" + CGI.escape(credential_hash[0..6])
61
64
  else
62
- query_string = query_string + "&hashes=" + CGI.escape(credential_hash);
65
+ query_string = query_string + "&partialHashes=" + CGI.escape(credential_hash[0..6])
63
66
  end
64
67
  end
65
68
  end
66
69
  end
67
70
  end
68
71
 
69
- if (query_string.length > 0)
72
+ if query_string.length > 0
70
73
  creds_response = make_rest_call(
71
- @baseURL + Constants::CREDENTIALS_API_PATH + query_string, "GET", nil)
72
- return creds_response != "404"
74
+ @baseURL + Constants::CREDENTIALS_API_PATH + query_string, "GET", nil)
75
+
76
+ if creds_response != "404"
77
+ creds_result = JSON.parse(creds_response, object_class: OpenStruct)
78
+ creds_result.candidateHashes.each do |candidateHash|
79
+ if credential_hashes.include? candidateHash
80
+ return true
81
+ end
82
+ end
83
+ end
73
84
  end
74
85
  end
75
86
 
@@ -77,21 +88,36 @@ module Enzoic
77
88
  end
78
89
 
79
90
  def check_password(password)
91
+ md5 = Hashing.md5(password)
92
+ sha1 = Hashing.sha1(password)
93
+ sha256 = Hashing.sha256(password)
94
+
80
95
  response = make_rest_call(
81
- @baseURL + Constants::PASSWORDS_API_PATH +
82
- "?md5=" + Hashing.md5(password) +
83
- "&sha1=" + Hashing.sha1(password) +
84
- "&sha256=" + Hashing.sha256(password),
85
- "GET", nil)
96
+ @baseURL + Constants::PASSWORDS_API_PATH, "POST",
97
+ '{' +
98
+ '"partialMD5":"' + md5[0..6] + '",' +
99
+ '"partialSHA1":"' + sha1[0..6] + '",' +
100
+ '"partialSHA256":"' + sha256[0..6] + '"' +
101
+ '}')
86
102
 
87
- return response != "404"
103
+ if response != "404"
104
+ result = JSON.parse(response, object_class: OpenStruct)
105
+
106
+ result.candidates.each do |candidate|
107
+ if candidate.md5 == md5 || candidate.sha1 == sha1 || candidate.sha256 == sha256
108
+ return true
109
+ end
110
+ end
111
+ end
112
+
113
+ return false
88
114
  end
89
115
 
90
116
  def get_exposures_for_user(username)
91
- response = make_rest_call(@baseURL + Constants::EXPOSURES_API_PATH + "?username=" + Hashing.sha256(username),
92
- "GET", nil)
117
+ response = make_rest_call(@baseURL + Constants::EXPOSURES_API_PATH + "?username=" + Hashing.sha256(username.downcase),
118
+ "GET", nil)
93
119
 
94
- if (response == "404")
120
+ if response == "404"
95
121
  # don't have this email in the DB - return empty response
96
122
  return JSON.parse('{ "count": 0, "exposures": [] }', object_class: OpenStruct)
97
123
  else
@@ -102,9 +128,9 @@ module Enzoic
102
128
 
103
129
  def get_exposure_details(exposure_id)
104
130
  response = make_rest_call(@baseURL + Constants::EXPOSURES_API_PATH + "?id=" + CGI.escape(exposure_id),
105
- "GET", nil)
131
+ "GET", nil)
106
132
 
107
- if (response != "404")
133
+ if response != "404"
108
134
  # deserialize response
109
135
  return JSON.parse(response, object_class: OpenStruct)
110
136
  else
@@ -112,82 +138,176 @@ module Enzoic
112
138
  end
113
139
  end
114
140
 
115
- private
116
- def make_rest_call(rest_url, method, body)
117
- begin
118
- response = RestClient::Request.execute(method: method, url: rest_url,
119
- headers: { content_type: :json, accept: :json, authorization: @authString })
120
- return response.body
121
- rescue RestClient::NotFound
122
- return "404"
123
- end
141
+ def get_passwords_for_user(username)
142
+ response = make_rest_call(@baseURL + Constants::ACCOUNTS_API_PATH + "?username=" +
143
+ Hashing.sha256(username.downcase) + "&includePasswords=1",
144
+ "GET", nil)
145
+
146
+ if response == "404"
147
+ # don't have this email in the DB - return empty response
148
+ return JSON.parse('{ "lastBreachDate": null, "passwords": [] }', object_class: OpenStruct)
149
+ else
150
+ # deserialize response
151
+ return JSON.parse(response, object_class: OpenStruct)
124
152
  end
153
+ end
125
154
 
126
- def calc_credential_hash(username, password, salt, hash_spec)
127
- password_hash = calc_password_hash(hash_spec["hashType"], password, hash_spec["salt"])
155
+ private
128
156
 
129
- if (password_hash != nil)
130
- return Hashing.argon2_raw(username + "$" + password_hash, salt)
131
- else
132
- return nil
133
- end
157
+ def make_rest_call(rest_url, method, body)
158
+ begin
159
+ response = RestClient::Request.execute(method: method, url: rest_url,
160
+ payload: body,
161
+ headers: { content_type: :json, accept: :json, authorization: @authString })
162
+ return response.body
163
+ rescue RestClient::NotFound
164
+ return "404"
134
165
  end
166
+ end
135
167
 
136
- def calc_password_hash(password_type, password, salt)
137
- case password_type
138
- when PasswordType::MD5
139
- return Hashing.md5(password)
140
- when PasswordType::SHA1
141
- return Hashing.sha1(password)
142
- when PasswordType::SHA256
143
- return Hashing.sha256(password)
144
- when PasswordType::SHA512
145
- return Hashing.sha512(password)
146
- when PasswordType::IPBoard_MyBB
147
- if (salt != nil && salt.length > 0)
148
- return Hashing.mybb(password, salt)
149
- end
150
- when PasswordType::VBulletinPre3_8_5
151
- if (salt != nil && salt.length > 0)
152
- return Hashing.vbulletin(password, salt)
153
- end
154
- when PasswordType::VBulletinPost3_8_5
155
- if (salt != nil && salt.length > 0)
156
- return Hashing.vbulletin(password, salt)
157
- end
158
- when PasswordType::BCrypt
159
- if (salt != nil && salt.length > 0)
160
- return Hashing.bcrypt(password, salt)
161
- end
162
- when PasswordType::CRC32
163
- return Hashing.crc32(password)
164
- when PasswordType::PHPBB3
165
- if (salt != nil && salt.length > 0)
166
- return Hashing.phpbb3(password, salt)
167
- end
168
- when PasswordType::CustomAlgorithm1
169
- if (salt != nil && salt.length > 0)
170
- return Hashing.custom_algorithm1(password, salt)
171
- end
172
- when PasswordType::CustomAlgorithm2
173
- if (salt != nil && salt.length > 0)
174
- return Hashing.custom_algorithm2(password, salt)
175
- end
176
- when PasswordType::MD5Crypt
177
- if (salt != nil && salt.length > 0)
178
- return Hashing.md5crypt(password, salt)
179
- end
180
- when PasswordType::CustomAlgorithm4
181
- if (salt != nil && salt.length > 0)
182
- return Hashing.custom_algorithm4(password, salt)
183
- end
184
- end
168
+ def calc_credential_hash(username, password, salt, hash_spec)
169
+ password_hash = calc_password_hash(hash_spec["hashType"], password, hash_spec["salt"])
185
170
 
171
+ if password_hash != nil
172
+ return Hashing.argon2_raw(username.downcase + "$" + password_hash, salt)
173
+ else
186
174
  return nil
187
175
  end
176
+ end
188
177
 
189
- def calc_auth_string(apiKey, secret)
190
- return "basic " + Base64.strict_encode64(apiKey + ":" + secret);
178
+ def calc_password_hash(password_type, password, salt)
179
+ case password_type
180
+ when PasswordType::MD5
181
+ return Hashing.md5(password)
182
+ when PasswordType::SHA1
183
+ return Hashing.sha1(password)
184
+ when PasswordType::SHA256
185
+ return Hashing.sha256(password)
186
+ when PasswordType::SHA512
187
+ return Hashing.sha512(password)
188
+ when PasswordType::IPBoard_MyBB
189
+ if salt != nil && salt.length > 0
190
+ return Hashing.mybb(password, salt)
191
+ end
192
+ when PasswordType::VBulletinPre3_8_5
193
+ if salt != nil && salt.length > 0
194
+ return Hashing.vbulletin(password, salt)
195
+ end
196
+ when PasswordType::VBulletinPost3_8_5
197
+ if salt != nil && salt.length > 0
198
+ return Hashing.vbulletin(password, salt)
199
+ end
200
+ when PasswordType::BCrypt
201
+ if salt != nil && salt.length > 0
202
+ return Hashing.bcrypt(password, salt)
203
+ end
204
+ when PasswordType::CRC32
205
+ return Hashing.crc32(password)
206
+ when PasswordType::PHPBB3
207
+ if salt != nil && salt.length > 0
208
+ return Hashing.phpbb3(password, salt)
209
+ end
210
+ when PasswordType::CustomAlgorithm1
211
+ if salt != nil && salt.length > 0
212
+ return Hashing.custom_algorithm1(password, salt)
213
+ end
214
+ when PasswordType::CustomAlgorithm2
215
+ if salt != nil && salt.length > 0
216
+ return Hashing.custom_algorithm2(password, salt)
217
+ end
218
+ when PasswordType::MD5Crypt
219
+ if salt != nil && salt.length > 0
220
+ return Hashing.md5crypt(password, salt)
221
+ end
222
+ when PasswordType::CustomAlgorithm4
223
+ if salt != nil && salt.length > 0
224
+ return Hashing.custom_algorithm4(password, salt)
225
+ end
226
+ when PasswordType::CustomAlgorithm5
227
+ if salt != nil && salt.length > 0
228
+ return Hashing.custom_algorithm5(password, salt)
229
+ end
230
+ when PasswordType::OsCommerce_AEF
231
+ if salt != nil && salt.length > 0
232
+ return Hashing.osCommerce_AEF(password, salt)
233
+ end
234
+ when PasswordType::DESCrypt
235
+ if salt != nil && salt.length > 0
236
+ return Hashing.desCrypt(password, salt)
237
+ end
238
+ when PasswordType::MySQLPre4_1
239
+ return Hashing.mySQLPre4_1(password)
240
+ when PasswordType::MySQLPost4_1
241
+ return Hashing.mySQLPost4_1(password)
242
+ when PasswordType::PunBB
243
+ if salt != nil && salt.length > 0
244
+ return Hashing.punBB(password, salt)
245
+ end
246
+ when PasswordType::CustomAlgorithm6
247
+ if salt != nil && salt.length > 0
248
+ return Hashing.custom_algorithm6(password, salt)
249
+ end
250
+ when PasswordType::PartialMD5_20
251
+ return Hashing.partial_md5_20(password)
252
+ when PasswordType::AVE_DataLife_Diferior
253
+ return Hashing.ave_datalife_diferior(password)
254
+ when PasswordType::DjangoMD5
255
+ if salt != nil && salt.length > 0
256
+ return Hashing.django_md5(password, salt)
257
+ end
258
+ when PasswordType::DjangoSHA1
259
+ if salt != nil && salt.length > 0
260
+ return Hashing.django_sha1(password, salt)
261
+ end
262
+ when PasswordType::PartialMD5_29
263
+ return Hashing.partial_md5_29(password)
264
+ when PasswordType::PliggCMS
265
+ if salt != nil && salt.length > 0
266
+ return Hashing.pligg_cms(password, salt)
267
+ end
268
+ when PasswordType::RunCMS_SMF1_1
269
+ if salt != nil && salt.length > 0
270
+ return Hashing.runcms_smf1_1(password, salt)
271
+ end
272
+ when PasswordType::NTLM
273
+ return Hashing.ntlm(password)
274
+ when PasswordType::SHA1Dash
275
+ if salt != nil && salt.length > 0
276
+ return Hashing.sha1dash(password, salt)
277
+ end
278
+ when PasswordType::SHA384
279
+ return Hashing.sha384(password)
280
+ when PasswordType::CustomAlgorithm7
281
+ if salt != nil && salt.length > 0
282
+ return Hashing.custom_algorithm7(password, salt)
283
+ end
284
+ when PasswordType::CustomAlgorithm9
285
+ if salt != nil && salt.length > 0
286
+ return Hashing.custom_algorithm9(password, salt)
287
+ end
288
+ when PasswordType::SHA512Crypt
289
+ if salt != nil && salt.length > 0
290
+ return Hashing.sha512crypt(password, salt)
291
+ end
292
+ when PasswordType::CustomAlgorithm10
293
+ if salt != nil && salt.length > 0
294
+ return Hashing.custom_algorithm10(password, salt)
295
+ end
296
+ when PasswordType::SHA256Crypt
297
+ if salt != nil && salt.length > 0
298
+ return Hashing.sha256crypt(password, salt)
299
+ end
300
+ when PasswordType::AuthMeSHA256
301
+ if salt != nil && salt.length > 0
302
+ return Hashing.authMeSHA256(password, salt)
303
+ end
304
+ else
305
+ return nil
191
306
  end
307
+ end
308
+
309
+ def calc_auth_string(api_key, secret)
310
+ return "basic " + Base64.strict_encode64(api_key + ":" + secret)
311
+ end
192
312
  end
193
313
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: enzoic
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.3
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Enzoic
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-08-27 00:00:00.000000000 Z
11
+ date: 2022-10-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -116,22 +116,22 @@ dependencies:
116
116
  name: bundler
117
117
  requirement: !ruby/object:Gem::Requirement
118
118
  requirements:
119
- - - "~>"
120
- - !ruby/object:Gem::Version
121
- version: 2.0.2
122
119
  - - ">="
123
120
  - !ruby/object:Gem::Version
124
- version: 2.0.2
121
+ version: 2.2.11
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 2.2.11
125
125
  type: :development
126
126
  prerelease: false
127
127
  version_requirements: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - "~>"
130
- - !ruby/object:Gem::Version
131
- version: 2.0.2
132
129
  - - ">="
133
130
  - !ruby/object:Gem::Version
134
- version: 2.0.2
131
+ version: 2.2.11
132
+ - - "~>"
133
+ - !ruby/object:Gem::Version
134
+ version: 2.2.11
135
135
  - !ruby/object:Gem::Dependency
136
136
  name: rake
137
137
  requirement: !ruby/object:Gem::Requirement
@@ -307,8 +307,8 @@ files:
307
307
  - ext/phc-winner-argon2/src/genkat.c
308
308
  - ext/phc-winner-argon2/src/genkat.h
309
309
  - ext/phc-winner-argon2/src/opt.c
310
- - ext/phc-winner-argon2/src/opt.o
311
310
  - ext/phc-winner-argon2/src/ref.c
311
+ - ext/phc-winner-argon2/src/ref.o
312
312
  - ext/phc-winner-argon2/src/run.c
313
313
  - ext/phc-winner-argon2/src/test.c
314
314
  - ext/phc-winner-argon2/src/thread.c
@@ -361,8 +361,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
361
361
  - !ruby/object:Gem::Version
362
362
  version: '0'
363
363
  requirements: []
364
- rubyforge_project:
365
- rubygems_version: 2.5.2.3
364
+ rubygems_version: 3.0.3.1
366
365
  signing_key:
367
366
  specification_version: 4
368
367
  summary: Ruby library for Enzoic API
Binary file