Merge "Add support for bcrypt_sha256 hasher"
This commit is contained in:
commit
be05fb3f11
@ -27,6 +27,7 @@ CONF = keystone.conf.CONF
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
SUPPORTED_HASHERS = frozenset([passlib.hash.bcrypt,
|
||||
passlib.hash.bcrypt_sha256,
|
||||
passlib.hash.scrypt,
|
||||
passlib.hash.pbkdf2_sha512,
|
||||
passlib.hash.sha512_crypt])
|
||||
@ -39,12 +40,26 @@ _HASHER_NAME_MAP = {hasher.name: hasher for hasher in SUPPORTED_HASHERS}
|
||||
# '$<ident>$<metadata>$<hash>') so we can do a fast-lookup on the hasher to
|
||||
# use. If has hasher has multiple ident options it is encoded in the
|
||||
# .ident_values attribute whereas hashers that have a single option
|
||||
# (sha512_crypt) only has the .ident attribute.
|
||||
# ( ) only has the .ident attribute.
|
||||
# NOTE(noonedeadpunk): Though bcrypt_sha256 does define <ident> as part of
|
||||
# the metadata, actual indent is represented with a <prefix> instead.
|
||||
def _get_hash_ident(hashers):
|
||||
for hasher in hashers:
|
||||
if hasattr(hasher, 'prefix'):
|
||||
ident = (getattr(hasher, 'prefix'),)
|
||||
elif hasattr(hasher, 'ident_values'):
|
||||
ident = getattr(hasher, 'ident_values')
|
||||
else:
|
||||
ident = (getattr(hasher, 'ident'),)
|
||||
yield (hasher, ident)
|
||||
|
||||
|
||||
_HASHER_IDENT_MAP = {
|
||||
prefix: module for module, prefix in itertools.chain(
|
||||
*[zip([mod] * len(getattr(mod, 'ident_values', (mod.ident,))),
|
||||
getattr(mod, 'ident_values', (mod.ident,)))
|
||||
for mod in SUPPORTED_HASHERS])}
|
||||
*[zip([mod] * len(ident), ident)
|
||||
for mod, ident in _get_hash_ident(SUPPORTED_HASHERS)]
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
def _get_hasher_from_ident(hashed):
|
||||
|
@ -114,7 +114,7 @@ Maximum number of entities that will be returned in an identity collection.
|
||||
|
||||
password_hash_algorithm = cfg.StrOpt(
|
||||
'password_hash_algorithm',
|
||||
choices=['bcrypt', 'scrypt', 'pbkdf2_sha512'],
|
||||
choices=['bcrypt', 'bcrypt_sha256', 'scrypt', 'pbkdf2_sha512'],
|
||||
default='bcrypt',
|
||||
help=utils.fmt("""
|
||||
The password hashing algorithm to use for passwords stored within keystone.
|
||||
|
@ -145,6 +145,17 @@ class UtilsTestCase(unit.BaseTestCase):
|
||||
common_utils.hash_password,
|
||||
invalid_length_password)
|
||||
|
||||
def test_bcrypt_sha256_not_truncate_password(self):
|
||||
self.config_fixture.config(strict_password_check=True)
|
||||
self.config_fixture.config(group='identity',
|
||||
password_hash_algorithm='bcrypt_sha256')
|
||||
password = '0' * 128
|
||||
password_verified = \
|
||||
common_utils.verify_length_and_trunc_password(password)
|
||||
hashed = common_utils.hash_password(password)
|
||||
self.assertTrue(common_utils.check_password(password, hashed))
|
||||
self.assertEqual(password.encode('utf-8'), password_verified)
|
||||
|
||||
def _create_test_user(self, password=OPTIONAL):
|
||||
user = {"name": "hthtest"}
|
||||
if password is not self.OPTIONAL:
|
||||
|
@ -0,0 +1,6 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Added support for the ``bcrypt_sha256`` password hashing algorythm, which
|
||||
does workaround limitation on a password length BCrypt have by running the
|
||||
password through HMAC-SHA2-256 first.
|
Loading…
Reference in New Issue
Block a user