summaryrefslogtreecommitdiff
path: root/docs/lib
diff options
context:
space:
mode:
authorEli Collins <elic@assurancetechnologies.com>2011-03-28 00:16:59 -0400
committerEli Collins <elic@assurancetechnologies.com>2011-03-28 00:16:59 -0400
commiteeb244787205ba1139ad8cf971bfd939af8bbbd0 (patch)
tree6367e10989703f8022a25f9c533ca84ea9706455 /docs/lib
parent7c7bcf5d4eb3cc929bb7ab4411515dd042d0f0e5 (diff)
downloadpasslib-eeb244787205ba1139ad8cf971bfd939af8bbbd0.tar.gz
added support for a bunch of PBKDF2 hash schemes
* pbkdf2_sha1, pbkdf2_sha256, pbkdf2_sha512 -- 3 custom schemes defined by passlib * dlitz_pbkdf2_sha1 -- Dwayne Litzenberger's PBKDF2 crypt * grub_pbkdf2_sha512 -- Grub2's PBKDF2 hash format * two util support functions: adapted_b64_(encode|decode) * UTs and docs for all of the above
Diffstat (limited to 'docs/lib')
-rw-r--r--docs/lib/passlib.hash.pbkdf2_digests.rst191
-rw-r--r--docs/lib/passlib.hash.rst1
-rw-r--r--docs/lib/passlib.utils.h64.rst2
3 files changed, 194 insertions, 0 deletions
diff --git a/docs/lib/passlib.hash.pbkdf2_digests.rst b/docs/lib/passlib.hash.pbkdf2_digests.rst
new file mode 100644
index 0000000..d2906b5
--- /dev/null
+++ b/docs/lib/passlib.hash.pbkdf2_digests.rst
@@ -0,0 +1,191 @@
+==========================================================
+:samp:`passlib.hash.pbkdf2_{digest}` - PBKDF2-based Hashes
+==========================================================
+
+.. index:: pbkdf2; password hashes, grub, grub; grub-mkpasswd-pbkdf2
+
+.. currentmodule:: passlib.hash
+
+Overview
+========
+PassLib provides support for a number of hashes based
+on the PBKDF2 [#pbkdf2]_ algorithm. PBKDF2 is ideally
+suited as the basis for a password hash, as it provides
+variable length salts, variable number of rounds,
+and (in combination with HMAC) can be tailored
+to use almost any cryptographic hash as the basis
+for it's operation.
+
+PassLib supports 5 PBKDF2-based hash schemes:
+
+* PassLib's PBKDF2 hashes -- :class:`!pbkdf2_sha1`,
+ :class:`!pbkdf2_sha256`, :class:`!pbkdf2_sha512` --
+ are three custom schemes defined and provided by PassLib.
+ They have a straightforward implementation,
+ and a format almost identical to that of :class:`sha512_crypt`.
+ Thus, while they are currently only implemented within PassLib,
+ they should be secure and extremely portable.
+
+* :class:`!dlitz_pbkdf2_sha1` provides an implementation of Dwayne Litzenberger's
+ PBKDF2-HMAC-SHA1 hash format [#dlitz]_.
+
+* :class:`!grub_pbkdf2_sha512` provides an implementation of Grub's PBKDF2-HMAC-SHA512
+ password hash [#grub]_, as generated by the :command:`grub-mkpasswd-pbkdf2` command,
+ and may be found in Grub2 configuration files.
+
+Usage
+=====
+These classes support both rounds and salts,
+and can be used in the exact same manner
+as :doc:`SHA-512 Crypt <passlib.hash.sha512_crypt>`.
+
+Interface
+=========
+.. autoclass:: pbkdf2_sha1()
+.. autoclass:: pbkdf2_sha256()
+.. autoclass:: pbkdf2_sha512()
+.. autoclass:: dlitz_pbkdf2_sha1()
+.. autoclass:: grub_pbkdf2_sha512()
+
+.. rst-class:: html-toggle
+
+Format & Algorithm
+==================
+
+Passlib's PBKDF2 Hashes
+-----------------------
+:class:`!pbkdf2_sha1`, :class:`!pbkdf2_sha256`, :class:`!pbkdf2_sha512`
+
+ An example :class:`!pbkdf2_sha256` hash (of ``password``):
+
+ ``$pbkdf2-sha256$6400$.6UI/S.nXIk8jcbdHx3Fhg$98jZicV16ODfEsEZeYPGHU3kbrUrvUEXOPimVSQDD44``.
+
+ All of the pbkdf2 hashes defined by passlib
+ follow the same format, :samp:`$pbkdf2-{digest}${rounds}${salt}${checksum}`.
+
+ * :samp:`$pbkdf2-{digest}$`` is used as the :ref:`modular-crypt-format` identifier
+ (``$pbkdf2-sha256$`` in the example).
+
+ * :samp:`{digest}` - this specifies the particular cryptographic hash
+ used in conjunction with HMAC to form PBKDF2's pseudorandom function
+ for that particular hash (``sha256`` in the example).
+
+ * :samp:`{rounds}` - the number of iterations that should be performed.
+ this is encoded as a positive decimal number with no zero-padding
+ (``6400`` in the example).
+
+ * :samp:`{salt}` - this is the :func:`adapted base64 encoding <passlib.utils.adapted_b64_encode>`
+ of the raw salt bytes passed into the PBKDF2 function.
+
+ * :samp:`{checksum}` - this is the :func:`adapted base64 encoding <passlib.utils.adapted_b64_encode>`
+ of the raw derived key bytes returned from the PBKDF2 function.
+ Each scheme uses output size of it's specific :samp:`{digest}`
+ as the size of the raw derived key. This is enlarged
+ by appromixately 4/3 by the base64 encoding,
+ resulting in a checksum size of 27, 43, and 86 for each of the respective algorithms.
+
+ The algorithm used by all of these schemes is deliberately identical and simple:
+ The password is encoded into UTF-8 if not already encoded,
+ and passed through :func:`~passlib.utils.pbkdf2.pbkdf2`
+ along with the decoded salt, and the number of rounds.
+ The result is then encoded using :func:`~passlib.utils.adapted_b64_encode`.
+
+ .. note::
+
+ The base64 encoding used by these functions uses the same
+ :mod:`hash64 <passlib.utils.h64>` character set as most
+ other Unix password hashes, but uses the standard base64 encoding scheme,
+ instead of hash64's alternate value mapping.
+
+ This was done deliberately to create a simple implementation using
+ common components, which none-the-less uses the same character set
+ as existing :ref:`modular-crypt-format` hashes, so it can be
+ used the same contexts without breaking charset expectations.
+
+Other PBKDF2 Hashes
+-------------------
+:class:`!dlitz_pbkdf2_sha1`
+
+ A example hash (of ``password``) is:
+
+ ``$p5k2$2710$.pPqsEwHD7MiECU0$b8TQ5AMQemtlaSgegw5Je.JBE3QQhLbO``.
+
+ All of this scheme's hashes have the format :samp:`$p5k2${rounds}${salt}${checksum}`,
+ where:
+
+ * ``$p5k2$`` is used as the :ref:`modular-crypt-format` identifier.
+
+ * :samp:`{rounds}` is the number of PBKDF2 iterations to perform,
+ stored as lowercase hexidecimal number with no zero-padding (in the example: ``2710`` or 10000 iterations).
+
+ * :samp:`{salt}` is the salt string, which can be any number of characters,
+ drawn from the :ref:`hash64 charset <h64charset>`
+ (``.pPqsEwHD7MiECU0`` in the example).
+
+ * :samp:`{checksum}` is 32 characters, which encode
+ the resulting 24-byte PBKDF2 derived key using :func:`~passlib.utils.adapted_b64_encode`
+ (``b8TQ5AMQemtlaSgegw5Je.JBE3QQhLbO`` in the example).
+
+ In order to generate the checksum, the password is first encoded into UTF-8 if it's unicode.
+ Then, the entire configuration string (all of the hash except the checksum, ie :samp:`$p5k2${rounds}${salt}`)
+ is used as the PBKDF2 salt. PBKDF2 is called using the encoded password, the full salt,
+ the specified number of rounds, and using HMAC-SHA1 as it's psuedorandom function.
+ 24 bytes of derived key are requested, and the resulting key is encoded and used
+ as the checksum portion of the hash.
+
+:class:`!grub_pbkdf2_sha512`
+
+ A example hash (of ``password``) is ::
+
+ grub.pbkdf2.sha512.10000.4483972AD2C52E1F590B3E2260795FDA9CA0B07B
+ 96FF492814CA9775F08C4B59CD1707F10B269E09B61B1E2D11729BCA8D62B7827
+ B25B093EC58C4C1EAC23137.DF4FCB5DD91340D6D31E33423E4210AD47C7A4DF9
+ FA16F401663BF288C20BF973530866178FE6D134256E4DBEFBD984B652332EED3
+ ACAED834FEA7B73CAE851D
+
+ All of this scheme's hashes have the format :samp:`grub.pbkdf2.sha512.{rounds}.{salt}.{checksum}`,
+ where :samp:`{rounds}` is the number of iteration stored in decimal,
+ :samp:`{salt}` is the salt string encoded using upper-case hexdecimal,
+ and :samp:`{checksum}` is the resulting 64-byte derived key, also
+ encoded in upper-case hexidecimal. It can be identified by the prefix ``grub.pdkdf2.sha512.``.
+
+ The algorithm used is the same as :class:`pbkdf2_sha1`: the password is encoded into UTF-8 if not already encoded,
+ and passed through :func:`~passlib.utils.pbkdf2.pbkdf2`
+ along with the decoded salt, and the number of rounds.
+ The result is then encoded into hexidecimal.
+
+Hash Translation
+----------------
+Note that despite encoding and format differences,
+:class:`!pbkdf2_sha512` and :class:`!grub_pbkdf2_sha512` share an identical algorithm,
+and one can be converted to the other using the following code::
+
+ >>> from passlib.hash import pbkdf2_sha512, grub_pbkdf2_sha512
+
+ >>> #given a pbkdf2_sha512 hash...
+ >>> h = pbkdf2_sha512.encrypt("password")
+ >>> h
+ '$pbkdf2-sha512$6400$y6vYff3SihJiqumIrNXwGw$NobVwyUlVI52/Cvrguwli5fX6XgKHNUf7fWWS2VgoWEevaTCiZx4OCYhwGFwzUAuz/g1zQVSIf.9JEb0BEVEEA'
+
+ >>> #it can be parsed into options
+ >>> hobj = pbkdf2_sha512.from_string(h)
+ >>> rounds, salt, chk = hobj.rounds, hobj.salt, hobj.checksum
+
+ >>> #and a new grub hash can be created
+ >>> gobj = grub_pbkdf2_sha512(rounds=rounds, salt=salt, checksum=chk)
+ >>> g = gobj.to_string()
+ >>> g
+
+ >>> grub_pbkdf2_sha512.verify("password", g)
+ True
+
+References
+==========
+
+.. [#hmac-sha1] While SHA1 has fallen to collision attacks, HMAC-SHA1 is still considered secure - `<http://www.schneier.com/blog/archives/2005/02/sha1_broken.html>`_.
+
+.. [#pbkdf2] The specification for the PBKDF2 algorithm - `<http://tools.ietf.org/html/rfc2898#section-5.2>`_.
+
+.. [#dlitz] Dwayne C. Litzenberger's PBKDF2 hash - `<http://www.dlitz.net/software/python-pbkdf2/>`_.
+
+.. [#grub] Information about Grub's password hashes - `<http://grub.enbug.org/Authentication>`_.
diff --git a/docs/lib/passlib.hash.rst b/docs/lib/passlib.hash.rst
index 27bcb4b..6f70689 100644
--- a/docs/lib/passlib.hash.rst
+++ b/docs/lib/passlib.hash.rst
@@ -64,6 +64,7 @@ the modular crypt format.
passlib.hash.apr_md5_crypt
passlib.hash.phpass
passlib.hash.nthash
+ passlib.hash.pbkdf2_digests
Database Schemes
----------------
diff --git a/docs/lib/passlib.utils.h64.rst b/docs/lib/passlib.utils.h64.rst
index 5ba5b6e..89c5bde 100644
--- a/docs/lib/passlib.utils.h64.rst
+++ b/docs/lib/passlib.utils.h64.rst
@@ -22,6 +22,8 @@ and decoding strings in that format.
when in fact bcrypt uses yet another ordering,
which does not match hash64 or other base64 schemes.
+.. _h64charset:
+
Constants
=========
.. data:: CHARS = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"