mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-16 22:43:00 +00:00
add hash rounds
default 16k
This commit is contained in:
@@ -353,20 +353,18 @@ class APIToken(Base):
|
|||||||
prefix = Column(Unicode)
|
prefix = Column(Unicode)
|
||||||
prefix_length = 4
|
prefix_length = 4
|
||||||
algorithm = "sha512"
|
algorithm = "sha512"
|
||||||
|
rounds = 16384
|
||||||
salt_bytes = 8
|
salt_bytes = 8
|
||||||
_token = None
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def token(self):
|
def token(self):
|
||||||
"""plaintext tokens will only be accessible for tokens created during this session"""
|
raise AttributeError("token is write-only")
|
||||||
return self._token
|
|
||||||
|
|
||||||
@token.setter
|
@token.setter
|
||||||
def token(self, token):
|
def token(self, token):
|
||||||
"""Store the hashed value and prefix for a token"""
|
"""Store the hashed value and prefix for a token"""
|
||||||
self.prefix = token[:self.prefix_length]
|
self.prefix = token[:self.prefix_length]
|
||||||
self.hashed = hash_token(token, salt=self.salt_bytes, algorithm=self.algorithm)
|
self.hashed = hash_token(token, rounds=self.rounds, salt=self.salt_bytes, algorithm=self.algorithm)
|
||||||
self._token = token
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<{cls}('{pre}...', user='{u}')>".format(
|
return "<{cls}('{pre}...', user='{u}')>".format(
|
||||||
|
@@ -150,7 +150,7 @@ def new_token(*args, **kwargs):
|
|||||||
return text_type(uuid.uuid4().hex)
|
return text_type(uuid.uuid4().hex)
|
||||||
|
|
||||||
|
|
||||||
def hash_token(token, salt=8, algorithm='sha256'):
|
def hash_token(token, salt=8, rounds=16384, algorithm='sha512'):
|
||||||
"""hash a token, and return it as `algorithm:salt:hash`
|
"""hash a token, and return it as `algorithm:salt:hash`
|
||||||
|
|
||||||
If `salt` is an integer, a random salt of that many bytes will be used.
|
If `salt` is an integer, a random salt of that many bytes will be used.
|
||||||
@@ -165,10 +165,11 @@ def hash_token(token, salt=8, algorithm='sha256'):
|
|||||||
bsalt = salt.encode('utf8')
|
bsalt = salt.encode('utf8')
|
||||||
btoken = token.encode('utf8', 'replace')
|
btoken = token.encode('utf8', 'replace')
|
||||||
h.update(bsalt)
|
h.update(bsalt)
|
||||||
h.update(btoken)
|
for i in range(rounds):
|
||||||
|
h.update(btoken)
|
||||||
digest = h.hexdigest()
|
digest = h.hexdigest()
|
||||||
|
|
||||||
return u"{algorithm}:{salt}:{digest}".format(**locals())
|
return u"{algorithm}:{rounds}:{salt}:{digest}".format(**locals())
|
||||||
|
|
||||||
|
|
||||||
def compare_token(compare, token):
|
def compare_token(compare, token):
|
||||||
@@ -176,8 +177,8 @@ def compare_token(compare, token):
|
|||||||
|
|
||||||
uses the same algorithm and salt of the hashed token for comparison
|
uses the same algorithm and salt of the hashed token for comparison
|
||||||
"""
|
"""
|
||||||
algorithm, salt, _ = compare.split(':', 2)
|
algorithm, srounds, salt, _ = compare.split(':')
|
||||||
hashed = hash_token(token, salt=salt, algorithm=algorithm)
|
hashed = hash_token(token, salt=salt, rounds=int(srounds), algorithm=algorithm)
|
||||||
if compare == hashed:
|
if compare == hashed:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
Reference in New Issue
Block a user