diff options
| author | Eli Collins <elic@assurancetechnologies.com> | 2011-03-28 00:16:59 -0400 |
|---|---|---|
| committer | Eli Collins <elic@assurancetechnologies.com> | 2011-03-28 00:16:59 -0400 |
| commit | eeb244787205ba1139ad8cf971bfd939af8bbbd0 (patch) | |
| tree | 6367e10989703f8022a25f9c533ca84ea9706455 /docs/lib | |
| parent | 7c7bcf5d4eb3cc929bb7ab4411515dd042d0f0e5 (diff) | |
| download | passlib-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.rst | 191 | ||||
| -rw-r--r-- | docs/lib/passlib.hash.rst | 1 | ||||
| -rw-r--r-- | docs/lib/passlib.utils.h64.rst | 2 |
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" |
