forked from pypi/legacy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
legacy_passwords.py
executable file
·67 lines (52 loc) · 2.15 KB
/
legacy_passwords.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import base64
import hashlib
import passlib.exc as exc
import passlib.utils.handlers as uh
from passlib.registry import get_crypt_handler
from passlib.utils import to_unicode
from passlib.utils.compat import uascii_to_str
passlib_bcrypt = get_crypt_handler("bcrypt")
class bcrypt_sha1(uh.StaticHandler):
name = "bcrypt_sha1"
_hash_prefix = u"$bcrypt_sha1$"
def _calc_checksum(self, secret):
# Hash the secret with sha1 first
secret = hashlib.sha1(secret).hexdigest()
# Hash it with bcrypt
return passlib_bcrypt.encrypt(secret)
def to_string(self):
assert self.checksum is not None
return uascii_to_str(self._hash_prefix + base64.b64encode(self.checksum))
@classmethod
def from_string(cls, hash, **context):
# default from_string() which strips optional prefix,
# and passes rest unchanged as checksum value.
hash = to_unicode(hash, "ascii", "hash")
hash = cls._norm_hash(hash)
# could enable this for extra strictness
##pat = cls._hash_regex
##if pat and pat.match(hash) is None:
## raise ValueError("not a valid %s hash" % (cls.name,))
prefix = cls._hash_prefix
if prefix:
if hash.startswith(prefix):
hash = hash[len(prefix):]
else:
raise exc.InvalidHashError(cls)
# Decode the base64 stored actual hash
hash = unicode(base64.b64decode(hash))
return cls(checksum=hash, **context)
@classmethod
def verify(cls, secret, hash, **context):
# NOTE: classes with multiple checksum encodings should either
# override this method, or ensure that from_string() / _norm_checksum()
# ensures .checksum always uses a single canonical representation.
uh.validate_secret(secret)
self = cls.from_string(hash, **context)
chk = self.checksum
if chk is None:
raise exc.MissingDigestError(cls)
# Actually use the verify from passlib_bcrypt after hashing the secret
# with sha1
secret = hashlib.sha1(secret).hexdigest()
return passlib_bcrypt.verify(secret, chk)