8000 Experimental code to test specifying password/salt hash order. · rinlevan/firebase-admin-python@3de3eb6 · GitHub
[go: up one dir, main page]

Skip to content

Commit 3de3eb6

Browse files
committed
Experimental code to test specifying password/salt hash order.
1 parent abd3980 commit 3de3eb6

File tree

2 files changed

+96
-20
lines changed

2 files changed

+96
-20
lines changed

firebase_admin/_user_import.py

Lines changed: 64 additions & 20 deletions
< 10000 /div>
< 10000 /tr>
Original file line numberDiff line numberDiff line change
@@ -276,112 +276,156 @@ def to_dict(self):
276276
return payload
277277

278278
@classmethod
279-
def _hmac(cls, name, key):
279+
def _hmac(cls, name, key, input_order=None):
280+
"""Creates a new HMAC based algorithm instance.
281+
282+
Args:
283+
name: The HMAC algorithm name.
284+
key: Signer key as a byte sequence.
285+
input_order: The salt + password order, either SALT_FIRST or PASSWORD_FIRST.
286+
287+
Returns:
288+
UserImportHash: A new ``UserImportHash``.
289+
"""
290+
291+
password_hash_order = None
292+
if input_order is 'SALT_FIRST':
293+
password_hash_order = 'SALT_AND_PASSWORD'
294+
elif input_order is 'PASSWORD_FIRST':
295+
password_hash_order = 'PASSWORD_AND_SALT'
280296
data = {
281-
'signerKey': b64_encode(_auth_utils.validate_bytes(key, 'key', required=True))
297+
'signerKey': b64_encode(_auth_utils.validate_bytes(key, 'key', required=True)),
298+
'passwordHashOrder': password_hash_order
282299
}
283300
return UserImportHash(name, data)
284301

285302
@classmethod
286-
def _basic_hash(cls, name, rounds):
287-
data = {'rounds': _auth_utils.validate_int(rounds, 'rounds', 0, 120000)}
303+
def _basic_hash(cls, name, rounds, input_order=None):
304+
"""Creates a new basic hash algorithm instance.
305+
306+
Args:
307+
name: The basic algorithm name.
308+
rounds: Number of rounds. This differs depending on the algorithm used.
309+
input_order: The salt + password order, either SALT_FIRST or PASSWORD_FIRST.
310+
311+
Returns:
312+
UserImportHash: A new ``UserImportHash``.
313+
"""
314+
315+
password_hash_order = None
316+
if input_order is 'SALT_FIRST':
317+
password_hash_order = 'SALT_AND_PASSWORD'
318+
elif input_order is 'PASSWORD_FIRST':
319+
password_hash_order = 'PASSWORD_AND_SALT'
320+
data = {
321+
'rounds': _auth_utils.validate_int(rounds, 'rounds', 0, 120000),
322+
'passwordHashOrder': password_hash_order
323+
}
288324
return UserImportHash(name, data)
289325

290326
@classmethod
291-
def hmac_sha512(cls, key):
327+
def hmac_sha512(cls, key, input_order=None):
292328
"""Creates a new HMAC SHA512 algorithm instance.
293329
294330
Args:
295331
key: Signer key as a byte sequence.
332+
input_order: The salt + password order, either SALT_FIRST or PASSWORD_FIRST.
296333
297334
Returns:
298335
UserImportHash: A new ``UserImportHash``.
299336
"""
300-
return cls._hmac('HMAC_SHA512', key)
337+
return cls._hmac('HMAC_SHA512', key, input_order)
301338

302339
@classmethod
303-
def hmac_sha256(cls, key):
340+
def hmac_sha256(cls, key, input_order=None):
304341
"""Creates a new HMAC SHA256 algorithm instance.
305342
306343
Args:
307344
key: Signer key as a byte sequence.
345+
input_order: The salt + password order, either SALT_FIRST or PASSWORD_FIRST.
308346
309347
Returns:
310348
UserImportHash: A new ``UserImportHash``.
311349
"""
312-
return cls._hmac('HMAC_SHA256', key)
350+
return cls._hmac('HMAC_SHA256', key, input_order)
313351

314352
@classmethod
315-
def hmac_sha1(cls, key):
353+
def hmac_sha1(cls, key, input_order=None):
316354
"""Creates a new HMAC SHA1 algorithm instance.
317355
318356
Args:
319357
key: Signer key as a byte sequence.
358+
input_order: The salt + password order, either SALT_FIRST or PASSWORD_FIRST.
320359
321360
Returns:
322361
UserImportHash: A new ``UserImportHash``.
323362
"""
324-
return cls._hmac('HMAC_SHA1', key)
363+
return cls._hmac('HMAC_SHA1', key, input_order)
325364

326365
@classmethod
327-
def hmac_md5(cls, key):
366+
def hmac_md5(cls, key, input_order=None):
328367
"""Creates a new HMAC MD5 algorithm instance.
329368
330369
Args:
331370
key: Signer key as a byte sequence.
371+
input_order: The salt + password order, either SALT_FIRST or PASSWORD_FIRST.
332372
333373
Returns:
334374
UserImportHash: A new ``UserImportHash``.
335375
"""
336-
return cls._hmac('HMAC_MD5', key)
376+
return cls._hmac('HMAC_MD5', key, input_order)
337377

338378
@classmethod
339-
def md5(cls, rounds):
379+
def md5(cls, rounds, input_order=None):
340380
"""Creates a new MD5 algorithm instance.
341381
342382
Args:
343383
rounds: Number of rounds. Must be an integer between 0 and 120000.
384+
input_order: The salt + password order, either SALT_FIRST or PASSWORD_FIRST.
344385
345386
Returns:
346387
UserImportHash: A new ``UserImportHash``.
347388
"""
348-
return cls._basic_hash('MD5', rounds)
389+
return cls._basic_hash('MD5', rounds, input_order)
349390

350391
@classmethod
351-
def sha1(cls, rounds):
392+
def sha1(cls, rounds, input_order=None):
352393
"""Creates a new SHA1 algorithm instance.
353394
354395
Args:
355396
rounds: Number of rounds. Must be an integer between 0 and 120000.
397+
input_order: The salt + password order, either SALT_FIRST or PASSWORD_FIRST.
356398
357399
Returns:
358400
UserImportHash: A new ``UserImportHash``.
359401
"""
360-
return cls._basic_hash('SHA1', rounds)
402+
return cls._basic_hash('SHA1', rounds, input_order)
361403

362404
@classmethod
363-
def sha256(cls, rounds):
405+
def sha256(cls, rounds, input_order=None):
364406
"""Creates a new SHA256 algorithm instance.
365407
366408
Args:
367409
rounds: Number of rounds. Must be an integer between 0 and 120000.
410+
input_order: The salt + password order, either SALT_FIRST or PASSWORD_FIRST.
368411
369412
Returns:
370413
UserImportHash: A new ``UserImportHash``.
371414
"""
372-
return cls._basic_hash('SHA256', rounds)
415+
return cls._basic_hash('SHA256', rounds, input_order)
373416

374417
@classmethod
375-
def sha512(cls, rounds):
418+
def sha512(cls, rounds, input_order=None):
376419
"""Creates a new SHA512 algorithm instance.
377420
378421
Args:
379422
rounds: Number of rounds. Must be an integer between 0 and 120000.
423+
input_order: The salt + password order, either SALT_FIRST or PASSWORD_FIRST.
380424
381425
Returns:
382426
UserImportHash: A new ``UserImportHash``.
383427
"""
384-
return cls._basic_hash('SHA512', rounds)
428+
return cls._basic_hash('SHA512', rounds, input_order)
385429

386430
@classmethod
387431
def pbkdf_sha1(cls, rounds):

tests/test_user_mgt.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,22 @@ def test_hmac(self, func, name):
759759
expected = {
760760
'hashAlgorithm': name,
761761
'signerKey': _user_import.b64_encode(b'key'),
762+
'passwordHashOrder': None
763+
}
764+
assert hmac.to_dict() == expected
765+
766+
@pytest.mark.parametrize('func,name', [
767+
(auth.UserImportHash.hmac_sha512, 'HMAC_SHA512'),
768+
(auth.UserImportHash.hmac_sha256, 'HMAC_SHA256'),
769+
(auth.UserImportHash.hmac_sha1, 'HMAC_SHA1'),
770+
(auth.UserImportHash.hmac_md5, 'HMAC_MD5'),
771+
])
772+
def test_hmac_hash_order(self, func, name):
773+
hmac = func(key=b'key', input_order='SALT_FIRST')
774+
expected = {
775+
'hashAlgorithm': name,
776+
'signerKey': _user_import.b64_encode(b'key'),
777+
'passwordHashOrder': 'SALT_AND_PASSWORD'
762778
}
763779
assert hmac.to_dict() == expected
764780

@@ -784,6 +800,22 @@ def test_basic(self, func, name):
784800
expected = {
785801
'hashAlgorithm': name,
786802
'rounds': 10,
803+
'passwordHashOrder': None
804+
}
805+
assert basic.to_dict() == expected
806+
807+
@pytest.mark.parametrize('func,name', [
808+
(auth.UserImportHash.sha512, 'SHA512'),
809+
(auth.UserImportHash.sha256, 'SHA256'),
810+
(auth.UserImportHash.sha1, 'SHA1'),
811+
(auth.UserImportHash.md5, 'MD5')
812+
])
813+
def test_basic_hash_order(self, func, name):
814+
basic = func(rounds=10, input_order='PASSWORD_FIRST')
815+
expected = {
816+
'hashAlgorithm': name,
817+
'rounds': 10,
818+
'passwordHashOrder': 'PASSWORD_AND_SALT'
787819
}
788820
assert basic.to_dict() == expected
789821

0 commit comments

Comments
 (0)
0