summaryrefslogtreecommitdiff
path: root/passlib/handlers/sha2_crypt.py
diff options
context:
space:
mode:
Diffstat (limited to 'passlib/handlers/sha2_crypt.py')
-rw-r--r--passlib/handlers/sha2_crypt.py103
1 files changed, 51 insertions, 52 deletions
diff --git a/passlib/handlers/sha2_crypt.py b/passlib/handlers/sha2_crypt.py
index 065102a..dbd848f 100644
--- a/passlib/handlers/sha2_crypt.py
+++ b/passlib/handlers/sha2_crypt.py
@@ -1,29 +1,28 @@
"""passlib.handlers.sha2_crypt - SHA256-Crypt / SHA512-Crypt"""
-#=========================================================
-#imports
-#=========================================================
-#core
+#=============================================================================
+# imports
+#=============================================================================
+# core
import hashlib
import logging; log = logging.getLogger(__name__)
from warnings import warn
-#site
-#libs
+# site
+# pkg
from passlib.utils import classproperty, h64, safe_crypt, test_crypt, \
repeat_string, to_unicode
from passlib.utils.compat import b, bytes, byte_elem_value, irange, u, \
uascii_to_str, unicode
import passlib.utils.handlers as uh
-#pkg
-#local
+# local
__all__ = [
"sha512_crypt",
"sha256_crypt",
]
-#==============================================================
+#=============================================================================
# pure-python backend, used by both sha256_crypt & sha512_crypt
# when crypt.crypt() backend is not available.
-#==============================================================
+#=============================================================================
_BNULL = b('\x00')
# pre-calculated offsets used to speed up C digest stage (see notes below).
@@ -69,9 +68,9 @@ def _raw_sha2_crypt(pwd, salt, rounds, use_512=False):
:returns:
encoded checksum chars
"""
- #=====================================================================
+ #===================================================================
# init & validate inputs
- #=====================================================================
+ #===================================================================
# validate secret
if isinstance(pwd, unicode):
@@ -107,14 +106,14 @@ def _raw_sha2_crypt(pwd, salt, rounds, use_512=False):
hash_len = 32
transpose_map = _256_transpose_map
- #=====================================================================
+ #===================================================================
# digest B - used as subinput to digest A
- #=====================================================================
+ #===================================================================
db = hash_const(pwd + salt + pwd).digest()
- #=====================================================================
+ #===================================================================
# digest A - used to initialize first round of digest C
- #=====================================================================
+ #===================================================================
# start out with pwd + salt
a_ctx = hash_const(pwd + salt)
a_ctx_update = a_ctx.update
@@ -131,10 +130,10 @@ def _raw_sha2_crypt(pwd, salt, rounds, use_512=False):
# finish A
da = a_ctx.digest()
- #=====================================================================
+ #===================================================================
# digest P from password - used instead of password itself
# when calculating digest C.
- #=====================================================================
+ #===================================================================
if pwd_len < 64:
# method this is faster under python, but uses O(pwd_len**2) memory
# so we don't use it for larger passwords, to avoid a potential DOS.
@@ -149,16 +148,16 @@ def _raw_sha2_crypt(pwd, salt, rounds, use_512=False):
dp = repeat_string(tmp_ctx.digest(), pwd_len)
assert len(dp) == pwd_len
- #=====================================================================
+ #===================================================================
# digest S - used instead of salt itself when calculating digest C
- #=====================================================================
+ #===================================================================
ds = hash_const(salt * (16 + byte_elem_value(da[0]))).digest()[:salt_len]
assert len(ds) == salt_len, "salt_len somehow > hash_len!"
- #=====================================================================
+ #===================================================================
# digest C - for a variable number of rounds, combine A, S, and P
# digests in various ways; in order to burn CPU time.
- #=====================================================================
+ #===================================================================
# NOTE: the original SHA256/512-Crypt specification performs the C digest
# calculation using the following loop:
@@ -227,14 +226,14 @@ def _raw_sha2_crypt(pwd, salt, rounds, use_512=False):
if tail & 1:
dc = hash_const(dc + data[pairs][0]).digest()
- #=====================================================================
+ #===================================================================
# encode digest using appropriate transpose map
- #=====================================================================
+ #===================================================================
return h64.encode_transposed_bytes(dc, transpose_map).decode("ascii")
-#=========================================================
+#=============================================================================
# handlers
-#=========================================================
+#=============================================================================
_UROUNDS = u("rounds=")
_UDOLLAR = u("$")
_UZERO = u("0")
@@ -242,9 +241,9 @@ _UZERO = u("0")
class _SHA2_Common(uh.HasManyBackends, uh.HasRounds, uh.HasSalt,
uh.GenericHandler):
"class containing common code shared by sha256_crypt & sha512_crypt"
- #=========================================================
+ #===================================================================
# class attrs
- #=========================================================
+ #===================================================================
# name - set by subclass
setting_kwds = ("salt", "rounds", "implicit_rounds", "salt_size")
# ident - set by subclass
@@ -262,9 +261,9 @@ class _SHA2_Common(uh.HasManyBackends, uh.HasRounds, uh.HasSalt,
_cdb_use_512 = False # flag for _calc_digest_builtin()
_rounds_prefix = None # ident + _UROUNDS
- #=========================================================
+ #===================================================================
# methods
- #=========================================================
+ #===================================================================
implicit_rounds = False
def __init__(self, implicit_rounds=None, **kwds):
@@ -331,9 +330,9 @@ class _SHA2_Common(uh.HasManyBackends, uh.HasRounds, uh.HasSalt,
self.salt, self.checksum or u(''))
return uascii_to_str(hash)
- #=========================================================
+ #===================================================================
# backends
- #=========================================================
+ #===================================================================
backends = ("os_crypt", "builtin")
_has_backend_builtin = True
@@ -355,9 +354,9 @@ class _SHA2_Common(uh.HasManyBackends, uh.HasRounds, uh.HasSalt,
else:
return self._calc_checksum_builtin(secret)
- #=========================================================
+ #===================================================================
# eoc
- #=========================================================
+ #===================================================================
class sha256_crypt(_SHA2_Common):
"""This class implements the SHA256-Crypt password hash, and follows the :ref:`password-hash-api`.
@@ -396,29 +395,29 @@ class sha256_crypt(_SHA2_Common):
.. versionadded:: 1.6
"""
- #=========================================================
+ #===================================================================
# class attrs
- #=========================================================
+ #===================================================================
name = "sha256_crypt"
ident = u("$5$")
checksum_size = 43
default_rounds = 80000 # current passlib default
- #=========================================================
+ #===================================================================
# backends
- #=========================================================
+ #===================================================================
@classproperty
def _has_backend_os_crypt(cls):
return test_crypt("test", "$5$rounds=1000$test$QmQADEXMG8POI5W"
"Dsaeho0P36yK3Tcrgboabng6bkb/")
- #=========================================================
- #eoc
- #=========================================================
+ #===================================================================
+ # eoc
+ #===================================================================
-#=========================================================
-#sha 512 crypt
-#=========================================================
+#=============================================================================
+# sha 512 crypt
+#=============================================================================
class sha512_crypt(_SHA2_Common):
"""This class implements the SHA512-Crypt password hash, and follows the :ref:`password-hash-api`.
@@ -457,18 +456,18 @@ class sha512_crypt(_SHA2_Common):
.. versionadded:: 1.6
"""
- #=========================================================
+ #===================================================================
# class attrs
- #=========================================================
+ #===================================================================
name = "sha512_crypt"
ident = u("$6$")
checksum_size = 86
_cdb_use_512 = True
default_rounds = 60000 # current passlib default
- #=========================================================
+ #===================================================================
# backend
- #=========================================================
+ #===================================================================
@classproperty
def _has_backend_os_crypt(cls):
return test_crypt("test", "$6$rounds=1000$test$2M/Lx6Mtobqj"
@@ -476,10 +475,10 @@ class sha512_crypt(_SHA2_Common):
"yWeBdRDx4DU.1H3eGmse6pgsOgDisWBG"
"I5c7TZauS0")
- #=========================================================
+ #===================================================================
# eoc
- #=========================================================
+ #===================================================================
-#=========================================================
+#=============================================================================
# eof
-#=========================================================
+#=============================================================================