summaryrefslogtreecommitdiff
path: root/docs/lib
diff options
context:
space:
mode:
authorEli Collins <elic@assurancetechnologies.com>2012-01-09 23:17:30 -0500
committerEli Collins <elic@assurancetechnologies.com>2012-01-09 23:17:30 -0500
commit1c449d2ddea632f3b7770f6d0c08f8435ea0cd18 (patch)
treef2d57863635c81c7267340eaf35c684ce6154420 /docs/lib
parent29e6db01cb272996a3e6f88cdbd8662f7024d605 (diff)
downloadpasslib-1c449d2ddea632f3b7770f6d0c08f8435ea0cd18.tar.gz
lots of work on scram hash
handler ------- * added 'scram' to default registry list * handler 'algs' keyword now parsed & validated correctly * digest names normalized -> IANA spec * saslprep() integrated into code * added config string format related ------- * added documentation (still needs cleaning up though) * added majority of UTs, still need to add a few edge cases other ----- * redid context->handler deprecation link - code now looks for handler._deprecated_detector(settings) to generate a callable, should be more efficient, and allow errors to be throw at bind-time instead of call-time. * pbkdf2() function now treats keylen = -1 as request for keylen = PRF digest size.
Diffstat (limited to 'docs/lib')
-rw-r--r--docs/lib/passlib.hash.rst1
-rw-r--r--docs/lib/passlib.hash.scram.rst136
2 files changed, 137 insertions, 0 deletions
diff --git a/docs/lib/passlib.hash.rst b/docs/lib/passlib.hash.rst
index 7c58cfe..fc108ab 100644
--- a/docs/lib/passlib.hash.rst
+++ b/docs/lib/passlib.hash.rst
@@ -94,6 +94,7 @@ they can be used compatibly along side other modular crypt format hashes.
passlib.hash.pbkdf2_digest
passlib.hash.cta_pbkdf2_sha1
passlib.hash.dlitz_pbkdf2_sha1
+ passlib.hash.scram
Special note should be made of the fallback helper,
which is not an actual hash scheme, but provides "disabled account"
diff --git a/docs/lib/passlib.hash.scram.rst b/docs/lib/passlib.hash.scram.rst
new file mode 100644
index 0000000..0a22c93
--- /dev/null
+++ b/docs/lib/passlib.hash.scram.rst
@@ -0,0 +1,136 @@
+===================================================================
+:class:`passlib.hash.scram` - SCRAM Hash
+===================================================================
+
+.. currentmodule:: passlib.hash
+
+SCRAM is a password-based challenge response protocol defined by :rfc:`5802`.
+While Passlib does not provide an implementation of SCRAM, applications
+which use SCRAM on the server side frequently need a way to store
+user passwords in a secure format that can be used to authenticate users over
+SCRAM.
+
+To accomplish this, Passlib provides the following
+:ref:`modular-crypt-format`-compatible password hash scheme which uses the
+``"$scram$"`` identifier. This format encodes a salt, rounds settings, and one
+or more :func:`~passlib.utils.pbkdf2.pbkdf2` digests, one digest for each
+of the hash algorithms the server wishes to support over SCRAM.
+
+Since this format is PBKDF2-based, it has equivalent security to
+Passlib's other :doc:`pbkdf2 hashes <passlib.hash.pbkdf2_digest>`,
+and can be used to authenticate users using either the SCRAM-specific class
+methods documentated below, or the normal :ref:`password-hash-api`.
+
+.. note::
+
+ If you aren't working with the SCRAM protocol, you probably
+ don't need to use this hash format.
+
+Usage
+=====
+This class can be used like any other Passlib hash, as follows::
+
+ >>> from passlib.hash import scram
+
+ >>> #generate new salt, encrypt password against default list of algorithms
+ >>> h = scram.encrypt("password")
+ >>> h
+ '$scram$40000$xxxxxx$sha-1=..............................,\
+ sha-256=........................................,\
+ sha-512=.........................................'
+
+ >>> #same, but with explict number of rounds
+ >>> scram.encrypt("password", rounds=10000)
+ '$scram$40000$xxxxxx$sha-1=..............................,\
+ sha-256=........................................,\
+ sha-512=.........................................'
+
+ >>> #check if hash is recognized
+ >>> scram.identify(h)
+ True
+ >>> #check if some other hash is recognized
+ >>> scram.identify('$1$3azHgidD$SrJPt7B.9rekpmwJwtON31')
+ False
+
+ >>> #verify correct password
+ >>> scram.verify("password", h)
+ True
+ >>> scram.verify("secret", h) #verify incorrect password
+ False
+
+Additionally, this class provides a number of useful methods
+for SCRAM-specific actions::
+
+ >>> from passlib.hash import scram
+ >>> # generate new salt, encrypt password against default list of algorithms
+ >>> h = scram.encrypt("password")
+ >>> h
+ '$scram$40000$xxxxxx$sha-1=..............................,\
+ sha-256=........................................,\
+ sha-512=.........................................'
+
+ >>> # generate new salt, encrypt password against specific list of algorithms
+ >>> # and choose explicit number of rounds
+ >>> h = scram.encrypt("password", rounds=1000, algs="sha-1,sha-256,md5")
+ >>> h
+ '$scram$40000$xxxxxx$sha-1=..............................,\
+ sha-256=........................................,\
+ md5=.........................................'
+
+ >>> # given a scram hash, retrieve the information SCRAM needs
+ >>> # to authenticate using a specific mechanism -
+ >>> # returns salt, rounds, digest
+ >>> scram.extact_digest_info("sha-1")
+ (b"xxxxxx", 400000, b".................")
+
+ >>> # given a scram hash, return list of digest algs present
+ >>> scram.extract_digest_algs(h)
+ ["sha-1","sha-256","md5"]
+
+ >>> # and a standalone helper that can calculated the SaltedPassword
+ >>> # portion of the SCRAM protocol.
+ >>> scram.derive_digest("password", b'xxxxx', 40000, 'sha-1')
+ b'..............................'
+
+Interface
+=========
+.. autoclass:: scram(algs=None, salt=None, rounds=None, strict=False)
+
+Format & Algorithm
+==================
+An example scram hash (of the string ``password``) is:
+
+ ``$6$rounds=40000$JvTuqzqw9bQ8iBl6$SxklIkW4gz00LvuOsKRCfNEllLciOqY/FSAwODHon45YTJEozmy.QAWiyVpuiq7XMTUMWbIWWEuQytdHkigcN/``.
+
+An scram hash string has the format :samp:`$scram${rounds}${salt}${alg}={digest}{,...}`, where:
+
+* ``$scram$`` is the prefix used to identify Passlib scram hashes,
+ following the :ref:`modular-crypt-format`
+
+* :samp:`{rounds}` is the decimal number of rounds to use (40000 in the example).
+
+* :samp:`{salt}` is a base64 encoded salt string (``JvTuqzqw9bQ8iBl6`` in the example).
+
+* :samp:`{alg}` is a lowercase IANA hash function name, which should
+ match the digest in the SCRAM mechanism name.
+
+* :samp:`{digest}` is a base64 digest for the specific algorithm.
+
+* There will be one or more `{alg}={digest}` pairs, separated by a comma;
+ per the SCRAM specification, the algorithm ``sha-1`` should always be present.
+
+There is also an alternate format :samp:`$scram${rounds}${salt}${alg}{,...}`
+which is used to represent a configuration string that doesn't contain
+any digests.
+
+The algorithm used to calculate each digest is
+``pbkdf2(salsprep(password).encode("utf-8"), salt, rounds, -1, alg)``,
+as laid out in the SCRAM specification. All digests
+verify against the same password, or the hash should be considered malformed.
+
+.. note::
+
+ This format is similar in spirit to the LDAP storage format for SCRAM hashes,
+ defined in :rfc:`5803`, except that it encodes everything into a single
+ string, and does not have any storage requirements (outside of the ability
+ to store 1024+ character ascii strings).