diff options
| author | Eli Collins <elic@assurancetechnologies.com> | 2011-04-29 00:08:17 -0400 |
|---|---|---|
| committer | Eli Collins <elic@assurancetechnologies.com> | 2011-04-29 00:08:17 -0400 |
| commit | c8d8eb0d9b1c753d342307b070fb1ad09cc351a6 (patch) | |
| tree | 491d6e0b3136edee39bc2001331eb4ed09a38afd /docs | |
| parent | bc98bc9188ed66d78ad3864443432690745da585 (diff) | |
| download | passlib-c8d8eb0d9b1c753d342307b070fb1ad09cc351a6.tar.gz | |
large rework of documentation; mainly to give more room to LDAP hashes, and document ldap CRYPT hashes
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/contents.rst | 8 | ||||
| -rw-r--r-- | docs/lib/passlib.apps.rst | 2 | ||||
| -rw-r--r-- | docs/lib/passlib.context-options.rst | 4 | ||||
| -rw-r--r-- | docs/lib/passlib.hash.atlassian_pbkdf2_sha1.rst | 60 | ||||
| -rw-r--r-- | docs/lib/passlib.hash.dlitz_pbkdf2_sha1.rst | 66 | ||||
| -rw-r--r-- | docs/lib/passlib.hash.grub_pbkdf2_sha512.rst | 84 | ||||
| -rw-r--r-- | docs/lib/passlib.hash.ldap_crypt.rst | 73 | ||||
| -rw-r--r-- | docs/lib/passlib.hash.ldap_digests.rst | 105 | ||||
| -rw-r--r-- | docs/lib/passlib.hash.ldap_std.rst | 102 | ||||
| -rw-r--r-- | docs/lib/passlib.hash.mysql323.rst | 2 | ||||
| -rw-r--r-- | docs/lib/passlib.hash.pbkdf2_digest.rst | 85 | ||||
| -rw-r--r-- | docs/lib/passlib.hash.pbkdf2_digests.rst | 222 | ||||
| -rw-r--r-- | docs/lib/passlib.hash.phpass.rst | 2 | ||||
| -rw-r--r-- | docs/lib/passlib.hash.plaintext.rst | 5 | ||||
| -rw-r--r-- | docs/lib/passlib.hash.rst | 158 | ||||
| -rw-r--r-- | docs/lib/passlib.hosts.rst | 114 | ||||
| -rw-r--r-- | docs/lib/passlib.registry.rst | 10 | ||||
| -rw-r--r-- | docs/modular_crypt_format.rst | 144 | ||||
| -rw-r--r-- | docs/overview.rst | 10 | ||||
| -rw-r--r-- | docs/password_hash_api.rst | 75 |
20 files changed, 812 insertions, 519 deletions
diff --git a/docs/contents.rst b/docs/contents.rst index 0388691..e8dbdbb 100644 --- a/docs/contents.rst +++ b/docs/contents.rst @@ -8,17 +8,19 @@ Table Of Contents install overview + password_hash_api + lib/passlib.hash + lib/passlib.context lib/passlib.apps lib/passlib.apache lib/passlib.hosts - password_hash_api - lib/passlib.hash lib/passlib.registry - lib/passlib.utils + modular_crypt_format + history copyright diff --git a/docs/lib/passlib.apps.rst b/docs/lib/passlib.apps.rst index 27e2058..3af39f1 100644 --- a/docs/lib/passlib.apps.rst +++ b/docs/lib/passlib.apps.rst @@ -53,7 +53,7 @@ Passlib provides two contexts related to ldap hashes: This object provides a pre-configured :class:`!CryptContext` instance for handling LDAPv2 password hashes. It recognizes all - the formats in the :doc:`ldap_digests listing <passlib.hash.ldap_digests>`. + the :ref:`standard ldap hashes <standard-ldap-hashes>`. It defaults to using the ``{SSHA}`` password hash. For times when there should be another default, using code such as the following:: diff --git a/docs/lib/passlib.context-options.rst b/docs/lib/passlib.context-options.rst index e799cdf..8a6a19e 100644 --- a/docs/lib/passlib.context-options.rst +++ b/docs/lib/passlib.context-options.rst @@ -34,7 +34,9 @@ of the :class:`!CryptContext` instance itself: Potential names can include the name of any class importable from the :mod:`passlib.hash` module. For example, to specify the :class:`passlib.hash.sha256_crypt` and the :class:`passlib.hash.des_crypt` schemes - should be supported for your new context, set ``schemes=["sha256_crypt", "des_crypt"]``. + should be supported for your new context:: + + >>> myctx = CryptContext(schemes=["sha256_crypt", "des_crypt"]) ``deprecated`` diff --git a/docs/lib/passlib.hash.atlassian_pbkdf2_sha1.rst b/docs/lib/passlib.hash.atlassian_pbkdf2_sha1.rst new file mode 100644 index 0000000..beed5ca --- /dev/null +++ b/docs/lib/passlib.hash.atlassian_pbkdf2_sha1.rst @@ -0,0 +1,60 @@ +=========================================================================== +:class:`passlib.hash.atlassian_pbkdf2_sha1` - Atlassian's PBKDF2-based Hash +=========================================================================== + +.. index:: atlassian, pbkdf2; password hash + +.. currentmodule:: passlib.hash + +This class provides an implementation of +the PBKDF2 based hash used by Atlassian in Jira and other products. +Note that unlike the most PBKDF2 hashes supported by Passlib, +this one uses a fixed number of rounds (10000). That is currently +a sufficient amount, but it cannot be altered; so this +scheme should only be used to read existing hashes, and not +used in new applications. + +.. seealso:: + + :doc:`passlib.hash.pbkdf2_digest <passlib.hash.pbkdf2_digest>` + for some other PBKDF2-based hashes. + +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:: atlassian_pbkdf2_sha1() + +Format & Algorithm +================== + +All of this scheme's hashes have the format :``{PKCS5S2}<data>``, +where :samp:`<data>` is a 64 character base64 encoded string; +which (when decoded), contains a 16 byte salt, +and a 32 byte checksum. + +A example hash (of ``password``) is: + + ``{PKCS5S2}DQIXJU038u4P7FdsuFTY/+35bm41kfjZa57UrdxHp2Mu3qF2uy+ooD+jF5t1tb8J`` + +Once decoded, the salt value (in hexdecimal octets) is: + + ``0d0217254d37f2ee0fec576cb854d8ff`` + +and the checksum value (in hexidecimal octets) is: + + ``edf96e6e3591f8d96b9ed4addc47a7632edea176bb2fa8a03fa3179b75b5bf09`` + +When calculating the checksum: +the password is encoded into UTF-8 if not already encoded. +Using the specified salt, and a fixed 10000 rounds, +PBKDF2-HMAC-SHA1 is used to generate a 32 byte key, +which appended to the salt and encoded in base64. + +References +========== +.. [#pbkdf2] The specification for the PBKDF2 algorithm - `<http://tools.ietf.org/html/rfc2898#section-5.2>`_. diff --git a/docs/lib/passlib.hash.dlitz_pbkdf2_sha1.rst b/docs/lib/passlib.hash.dlitz_pbkdf2_sha1.rst new file mode 100644 index 0000000..c220c9f --- /dev/null +++ b/docs/lib/passlib.hash.dlitz_pbkdf2_sha1.rst @@ -0,0 +1,66 @@ +======================================================================== +:class:`passlib.hash.dlitz_pbkdf2_sha1` - Dwayne Litzenger's PBKDF2 hash +======================================================================== + +.. index:: pbkdf2; password hash + +.. currentmodule:: passlib.hash + +This class provides an implementation of Dwayne Litzenberger's +PBKDF2-HMAC-SHA1 hash format [#dlitz]_. PBKDF2 is a key derivation function [#pbkdf2]_ +that is ideally suited as the basis for a password hash, as it provides +variable length salts, variable number of rounds. + +.. seealso:: + + :doc:`passlib.hash.pbkdf2_digest <passlib.hash.pbkdf2_digest>` + for some other PBKDF2-based hashes. + +Usage +===== +This class 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:: dlitz_pbkdf2_sha1() + +.. rst-class:: html-toggle + +Format & Algorithm +================== + +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. + +References +========== + +.. [#dlitz] The reference for this hash format - `<http://www.dlitz.net/software/python-pbkdf2/>`_. + +.. [#pbkdf2] The specification for the PBKDF2 algorithm - `<http://tools.ietf.org/html/rfc2898#section-5.2>`_. diff --git a/docs/lib/passlib.hash.grub_pbkdf2_sha512.rst b/docs/lib/passlib.hash.grub_pbkdf2_sha512.rst new file mode 100644 index 0000000..a9673d3 --- /dev/null +++ b/docs/lib/passlib.hash.grub_pbkdf2_sha512.rst @@ -0,0 +1,84 @@ +============================================================= +:class:`passlib.hash.grub_pbkdf2_sha512` - Grub's PBKDF2 Hash +============================================================= + +.. index:: pbkdf2; password hash + +.. currentmodule:: passlib.hash + +This class 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. +PBKDF2 is a key derivation function [#pbkdf2]_ +that is ideally suited as the basis for a password hash, as it provides +variable length salts, variable number of rounds. + +.. seealso:: + + :doc:`passlib.hash.pbkdf2_digest <passlib.hash.pbkdf2_digest>` + for some other PBKDF2-based hashes. + +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:: grub_pbkdf2_sha512() + +Format & Algorithm +================== + +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 +========== + +.. [#grub] Information about Grub's password hashes - `<http://grub.enbug.org/Authentication>`_. + +.. [#pbkdf2] The specification for the PBKDF2 algorithm - `<http://tools.ietf.org/html/rfc2898#section-5.2>`_. diff --git a/docs/lib/passlib.hash.ldap_crypt.rst b/docs/lib/passlib.hash.ldap_crypt.rst new file mode 100644 index 0000000..04e6f93 --- /dev/null +++ b/docs/lib/passlib.hash.ldap_crypt.rst @@ -0,0 +1,73 @@ +=========================================================== +:samp:`passlib.hash.ldap_{crypt}` - LDAP crypt() Wrappers +=========================================================== + +.. currentmodule:: passlib.hash + +Passlib provides support for all the standard +LDAP hash formats specified by :rfc:`2307`. +One of these, identified by RFC 2307 as the ``{CRYPT}`` scheme, +is somewhat different from the others. +Instead of specifying a password hashing scheme, +it's supposed to wrap the host OS's :func:`!crypt()`. + +Being host-dependant, the actual hashes supported +by this scheme may differ greatly between host systems. +In order to provide uniform support across platforms, +Passlib defines a corresponding :samp:`ldap_{xxx}_crypt` scheme +for each of the :ref:`standard unix hashes <standard-unix-hashes>`. + +.. seealso:: + + * :doc:`passlib.hash.ldap_std` - the other standard LDAP hashes. + + * :mod:`!passlib.apps` for a :ref:`list of premade ldap contexts <ldap-contexts>`. + +Usage +===== +These classes all wrap the underlying implementations, +and are mainly useful only for plugging them into a :class:`~passlib.context.CryptContext`. +However, they can be used directly as follows:: + + >>> from passlib.hash import ldap_md5_crypt as lmc + + >>> #encrypt password + >>> h = lmc.encrypt("password") + >>> h + '{CRYPT}$1$gwvn5BO0$3dyk8j.UTcsNUPrLMsU6/0' + + >>> lmc.identify(h) #check if hash is recognized + True + >>> lmc.identify('JQMuyS6H.AGMo') #check if some other hash is recognized + False + + >>> lmc.verify("password", h) #verify correct password + True + >>> lmc.verify("secret", h) #verify incorrect password + False + +Interface +========= +.. class:: ldap_des_crypt() +.. class:: ldap_bsdi_crypt() +.. class:: ldap_md5_crypt() +.. class:: ldap_bcrypt() +.. class:: ldap_sha1_crypt() +.. class:: ldap_sha256_crypt() +.. class:: ldap_sha512_crypt() + + All of these classes have the same interface as their corresponding + underlying hash (eg :class:`des_crypt`, :class:`md5_crypt`, etc). + +.. note:: + + In order to determine if a particular hash is actually supported + natively by your host OS, use an test such as + ``ldap_des_crypt.has_backend("os_crypt")`` or similar. + +References +========== + +.. [#pwd] The manpage for :command:`slappasswd` - `<http://gd.tuwien.ac.at/linuxcommand.org/man_pages/slappasswd8.html>`_. + +.. [#rfc] The basic format for these hashes is laid out in RFC 2307 - `<http://www.ietf.org/rfc/rfc2307.txt>`_ diff --git a/docs/lib/passlib.hash.ldap_digests.rst b/docs/lib/passlib.hash.ldap_digests.rst deleted file mode 100644 index 28f02a0..0000000 --- a/docs/lib/passlib.hash.ldap_digests.rst +++ /dev/null @@ -1,105 +0,0 @@ -=========================================================== -:samp:`passlib.hash.ldap_{digest}` - LDAP / RFC2307 Digests -=========================================================== - -.. currentmodule:: passlib.hash - -PassLib provides support for a most of the hashes -used by LDAP, as stored in the :rfc:`2307` format. -This includes ``{MD5}``, ``{SMD5}``, ``{SHA}``, ``{SSHA}``. -Many of these schemes are somewhat to very insecure, -and should not be used except when required. -The ``{CRYPT}`` scheme is supported by individual handlers -for each underlying crypt algorithm. - -.. seealso:: - - :mod:`!passlib.apps` for a :ref:`list of premade ldap contexts <ldap-contexts>`. - -Usage -===== -These classes all wrap the underlying hashlib implementations, -and are mainly useful only for plugging them into a :class:`~passlib.context.CryptContext`. -However, they can be used directly as follows:: - - >>> from passlib.hash import ldap_salted_md5 as lsm - - >>> #encrypt password - >>> h = lsm.encrypt("password") - >>> h - '{SMD5}OqsUXNHIhHbznxrqHoIM+ZT8DmE=' - - >>> hs.identify(h) #check if hash is recognized - True - >>> hs.identify('JQMuyS6H.AGMo') #check if some other hash is recognized - False - - >>> hs.verify("password", h) #verify correct password - True - >>> hs.verify("secret", h) #verify incorrect password - False - -Interface -========= -.. autoclass:: ldap_md5() -.. autoclass:: ldap_salted_md5() -.. autoclass:: ldap_sha1() -.. autoclass:: ldap_salted_sha1() -.. autoclass:: ldap_plaintext() - -As well, passlib supports the following `{CRYPT}` schemes, -which wrap their respective underlying unix crypt scheme: - -.. class:: ldap_des_crypt() -.. class:: ldap_bsdi_crypt() -.. class:: ldap_md5_crypt() -.. class:: ldap_bcrypt() -.. class:: ldap_sha1_crypt() -.. class:: ldap_sha256_crypt() -.. class:: ldap_sha512_crypt() - -.. rst-class:: html-toggle - -Format & Algorithm -================== -All of these classes follow a single basic format [#rfc]_: - -ldap_md5, ldap_sha1 - - These hashes have the format :samp:`{prefix}{checksum}`. - - * :samp:`{prefix}` is `{MD5}` for ldap_md5, - and `{SHA}` for ldap_sha1. - * :samp:`{checksum}` is the base64 encoding - of the raw message digest of the password, - using the appropriate digest algorithm. - - An example ldap_md5 hash (of ``password``) is ``{MD5}X03MO1qnZdYdgyfeuILPmQ==``. - An example ldap_sha1 hash (of ``password``) is ``{SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g=``. - -ldap_salted_md5, ldap_salted_sha1 - - These hashes have the format :samp:`{prefix}{data}`. - - * :samp:`{prefix}` is `{SMD5}` for ldap_salted_md5, - and `{SSHA}` for ldap_salted_sha1. - * :samp:`{data}` is the base64 encoding of :samp:`{checksum}{salt}`; - and in turn :samp:`{salt}` is a 4 byte binary salt, - and :samp:`{checksum}` is the raw digest of the - the string :samp:`{password}{salt}`, - using the appropriate digest algorithm. - - An example hash (of ``password``) is ``{SMD5}jNoSMNY0cybfuBWiaGlFw3Mfi/U=``. - After decoding, this results in a raw salt string ``s\x1f\x8b\xf5``, - and a raw MD5 checksum of ``\x8c\xda\x120\xd64s&\xdf\xb8\x15\xa2hiE\xc3``. - - An example hash (of ``password``) is ``{SSHA}pKqkNr1tq3wtQqk+UcPyA3HnA2NsU5NJ``. - After decoding, this results in a raw salt string ``lS\x93I``, - and a raw SHA1 checksum of ``\xa4\xaa\xa46\xbdm\xab|-B\xa9>Q\xc3\xf2\x03q\xe7\x03c``. - -References -========== - -.. [#pwd] The manpage for :command:`slappasswd` - `<http://gd.tuwien.ac.at/linuxcommand.org/man_pages/slappasswd8.html>`_. - -.. [#rfc] The basic format for these hashes is laid out in RFC 2307 - `<http://www.ietf.org/rfc/rfc2307.txt>`_ diff --git a/docs/lib/passlib.hash.ldap_std.rst b/docs/lib/passlib.hash.ldap_std.rst new file mode 100644 index 0000000..d38c3c0 --- /dev/null +++ b/docs/lib/passlib.hash.ldap_std.rst @@ -0,0 +1,102 @@ +============================================================= +:samp:`passlib.hash.ldap_{digest}` - RFC2307 Standard Digests +============================================================= + +.. currentmodule:: passlib.hash + +Passlib provides support for all the standard +LDAP hash formats specified by :rfc:`2307`. +This includes ``{MD5}``, ``{SMD5}``, ``{SHA}``, ``{SSHA}``. +Many of these schemes are somewhat to very insecure, +and should not be used except when required. + +.. note:: + + RFC 2307 also specifies a ``{CRYPT}`` scheme, + which is supposed to wrap the host OS's :func:`!crypt()`. + Being host-dependant, this scheme is somewhat different, + and is details in :doc:`passlib.hash.ldap_crypt`. + +.. seealso:: + + * :doc:`passlib.hash.ldap_crypt` + + * :mod:`!passlib.apps` for a :ref:`list of premade ldap contexts <ldap-contexts>`. + +Usage +===== +These classes all wrap the underlying hashlib implementations, +and are mainly useful only for plugging them into a :class:`~passlib.context.CryptContext`. +However, they can be used directly as follows:: + + >>> from passlib.hash import ldap_salted_md5 as lsm + + >>> #encrypt password + >>> h = lsm.encrypt("password") + >>> h + '{SMD5}OqsUXNHIhHbznxrqHoIM+ZT8DmE=' + + >>> lms.identify(h) #check if hash is recognized + True + >>> lms.identify('JQMuyS6H.AGMo') #check if some other hash is recognized + False + + >>> lms.verify("password", h) #verify correct password + True + >>> lms.verify("secret", h) #verify incorrect password + False + +Plain Hashes +============ +.. autoclass:: ldap_md5() +.. autoclass:: ldap_sha1() + +These hashes have the format :samp:`{prefix}{checksum}`. + +* :samp:`{prefix}` is `{MD5}` for ldap_md5, and `{SHA}` for ldap_sha1. +* :samp:`{checksum}` is the base64 encoding + of the raw message digest of the password, + using the appropriate digest algorithm. + +An example ldap_md5 hash (of ``password``) is ``{MD5}X03MO1qnZdYdgyfeuILPmQ==``. +An example ldap_sha1 hash (of ``password``) is ``{SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g=``. + +Salted Hashes +============= +.. autoclass:: ldap_salted_md5() +.. autoclass:: ldap_salted_sha1() + +These hashes have the format :samp:`{prefix}{data}`. + +* :samp:`{prefix}` is `{SMD5}` for ldap_salted_md5, + and `{SSHA}` for ldap_salted_sha1. +* :samp:`{data}` is the base64 encoding of :samp:`{checksum}{salt}`; + and in turn :samp:`{salt}` is a 4 byte binary salt, + and :samp:`{checksum}` is the raw digest of the + the string :samp:`{password}{salt}`, + using the appropriate digest algorithm. + +An example hash (of ``password``) is ``{SMD5}jNoSMNY0cybfuBWiaGlFw3Mfi/U=``. +After decoding, this results in a raw salt string ``s\x1f\x8b\xf5``, +and a raw MD5 checksum of ``\x8c\xda\x120\xd64s&\xdf\xb8\x15\xa2hiE\xc3``. + +An example hash (of ``password``) is ``{SSHA}pKqkNr1tq3wtQqk+UcPyA3HnA2NsU5NJ``. +After decoding, this results in a raw salt string ``lS\x93I``, +and a raw SHA1 checksum of ``\xa4\xaa\xa46\xbdm\xab|-B\xa9>Q\xc3\xf2\x03q\xe7\x03c``. + +Plaintext +========= +.. autoclass:: ldap_plaintext() + +This handler does not hash passwords at all, +rather it encoded them into UTF-8. +The only difference between this class and :class:`passlib.hash.plaintext` +is that this class will NOT recognize any strings using +the ``{SCHEME}HASH`` format. + +References +========== + +.. [#pwd] The manpage for :command:`slappasswd` - `<http://gd.tuwien.ac.at/linuxcommand.org/man_pages/slappasswd8.html>`_. + +.. [#rfc] The basic format for these hashes is laid out in RFC 2307 - `<http://www.ietf.org/rfc/rfc2307.txt>`_ diff --git a/docs/lib/passlib.hash.mysql323.rst b/docs/lib/passlib.hash.mysql323.rst index 7bbc129..81adb09 100644 --- a/docs/lib/passlib.hash.mysql323.rst +++ b/docs/lib/passlib.hash.mysql323.rst @@ -19,7 +19,7 @@ hash algorithm was introduced (see :class:`~passlib.hash.mysql41`). .. seealso:: - :mod:`!passlib.apps` for a :ref:`list of premade mysql contexts <mysql-contexts>`. + :mod:`!passlib.apps` for a list of predefined :ref:`mysql contexts <mysql-contexts>`. Usage ===== diff --git a/docs/lib/passlib.hash.pbkdf2_digest.rst b/docs/lib/passlib.hash.pbkdf2_digest.rst new file mode 100644 index 0000000..1014907 --- /dev/null +++ b/docs/lib/passlib.hash.pbkdf2_digest.rst @@ -0,0 +1,85 @@ +=============================================================== +:samp:`passlib.hash.pbkdf2_{digest}` - Simple PBKDF2 Hashes +=============================================================== + +.. index:: pbkdf2; password hash + +.. currentmodule:: passlib.hash + +PassLib provides three custom hash schemes based on the PBKDF2 [#pbkdf2]_ algorithm +which are compatible with the :ref:`modular crypt format <modular-crypt-format>`: +:class:`pbkdf2_sha1`, :class:`pbkdf2_sha256`, :class:`pbkdf2_sha512`. +They feature variable length salts, variable rounds. + +Security-wise, PBKDF2 is currently one of the leading key derivation functions, +and has no known security issues. +Though the original PBKDF2 specification uses the SHA-1 message digest, +it is not vulnerable to any of the known weaknesses of SHA-1 [#hmac-sha1]_, +and can be safely used. However, for those still concerned, SHA-256 and SHA-512 +versions are offered as well. + +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 +========= +.. class:: pbkdf2_sha1() + + except for the choice of message digest, + this class is the same as :class:`pbkdf2_sha512`. + +.. class:: pbkdf2_sha256() + + except for the choice of message digest, + this class is the same as :class:`pbkdf2_sha512`. + +.. autoclass:: pbkdf2_sha512() + +.. rst-class:: html-toggle + +Format & Algorithm +================== +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, the number of rounds, +and a prf built from HMAC + the respective message digest. +The result is then encoded using :func:`~passlib.utils.adapted_b64_encode`. + +References +========== +.. [#pbkdf2] The specification for the PBKDF2 algorithm - `<http://tools.ietf.org/html/rfc2898#section-5.2>`_, + part of :rfc:`2898`. + +.. [#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>`_. diff --git a/docs/lib/passlib.hash.pbkdf2_digests.rst b/docs/lib/passlib.hash.pbkdf2_digests.rst deleted file mode 100644 index 666bd83..0000000 --- a/docs/lib/passlib.hash.pbkdf2_digests.rst +++ /dev/null @@ -1,222 +0,0 @@ -========================================================== -: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. - -* :class:`!atlassian_pbkdf2_sha1` provides an implementation of - the PBKDF2 based hash used by Atlassian in Jira and other products. - Note that unlike the above PBKDF2 hashes, this one uses a fixed - number of rounds. - -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() -.. autoclass:: atlassian_pbkdf2_sha1() - -.. 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. - -:class:`!atlassian_pbkdf2_sha1` - - All of this scheme's hashes have the format :``{PKCS5S2}<data>``, - where :samp:`<data>` is a 64 character base64 encoded string; - which (when decoded), contains a 16 byte salt, - and a 32 byte checksum. - - A example hash (of ``password``) is: - - ``{PKCS5S2}DQIXJU038u4P7FdsuFTY/+35bm41kfjZa57UrdxHp2Mu3qF2uy+ooD+jF5t1tb8J`` - - Once decoded, the salt value (in hexdecimal octets) is: - - ``0d0217254d37f2ee0fec576cb854d8ff`` - - and the checksum value (in hexidecimal octets) is: - - ``edf96e6e3591f8d96b9ed4addc47a7632edea176bb2fa8a03fa3179b75b5bf09`` - - When calculating the checksum: - the password is encoded into UTF-8 if not already encoded. - Using the specified salt, and a fixed 10000 rounds, - PBKDF2-HMAC-SHA1 is used to generate a 32 byte key, - which appended to the salt and encoded in base64. - -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.phpass.rst b/docs/lib/passlib.hash.phpass.rst index c628005..a185a8c 100644 --- a/docs/lib/passlib.hash.phpass.rst +++ b/docs/lib/passlib.hash.phpass.rst @@ -1,3 +1,5 @@ +.. index:: phpass; portable hash + ================================================================== :class:`passlib.hash.phpass` - PHPass' Portable Hash ================================================================== diff --git a/docs/lib/passlib.hash.plaintext.rst b/docs/lib/passlib.hash.plaintext.rst index d8ad3ac..5d51ac1 100644 --- a/docs/lib/passlib.hash.plaintext.rst +++ b/docs/lib/passlib.hash.plaintext.rst @@ -9,6 +9,11 @@ This is, of course, ridiculously insecure; it is provided for backwards compatibility when migrating existing applications. *It should not be used* for any other purpose. +.. seealso:: + + * :class:`passlib.hash.ldap_plaintext` is probably more appropriate + to use in conjunction with other LDAP style hashes. + Usage ===== This class is mainly useful only for plugging into a :class:`~passlib.context.CryptContext`. diff --git a/docs/lib/passlib.hash.rst b/docs/lib/passlib.hash.rst index ac1afce..8a2e99c 100644 --- a/docs/lib/passlib.hash.rst +++ b/docs/lib/passlib.hash.rst @@ -1,33 +1,55 @@ -============================================ -:mod:`passlib.hash` - Password Hash Schemes -============================================ +============================================== +:mod:`passlib.hash` - Password Hashing Schemes +============================================== .. module:: passlib.hash :synopsis: all password hashes provided by PassLib -This module contains classes implementing each of the password hashes built into -passlib. As well, any external hashes registered using :func:`register_crypt_handler` -will be inserted into this module. +Overview +======== +The :mod:`!passlib.hash` module contains all the password hashes built into Passlib. +Each object within this package implements a different password hashing scheme, +but all have the same uniform interface. The hashes in this module can used in two ways: -Each class within this package implements a single password hashing scheme, -and follows passlib's :ref:`password-hash-api`. -While many applications may find it easier to use a :class:`CryptContext` -instance, or retreive handlers via :func:`get_crypt_handler`, they can -also be imported and used directly from this package, as in the following example: +They can be imported and used directly, as in the following example:: >>> from passlib.hash import md5_crypt - >>> hash = md5_crypt.encrypt("password") + >>> md5_crypt.encrypt("password") + '$1$IU54yC7Y$nI1wF8ltcRvaRHwMIjiJq1' -PassLib contains the following builtin password algorithms: +More commonly, they can be referenced by name +when constructing a custom :doc:`CryptContext <passlib.context>` object, +as in the following example:: + + >>> from passlib.context import CryptContext + >>> #note below that md5_crypt and des_crypt are both names of classes in passlib.hash + >>> pwd_context = CryptContext(["md5_crypt", "des_crypt"]) + >>> pwd_context.encrypt("password") + '$1$2y72Yi12$o6Yu2OyjN.9FiK.9HJ7i5.' + +.. seealso:: + + * the :ref:`password hash api <password-hash-api>` for details of the + interface used by all password hashes in this module. + +.. _mcf-hashes: + +Unix & "Modular Crypt" Hashes +============================= +Aside from the "archaic" schemes below, most modern Unix flavors +use password hashes which follow the :ref:`modular crypt format <modular-crypt-format>`, +allowing them to be easily distinguished when used within the same file. +The basic format :samp:`${scheme}${hash}` has also been adopted for use +by other applications and password hash schemes. .. _archaic-unix-schemes: Archaic Unix Schemes -------------------- -All these schemes are/were used by various unix flavors to store user passwords; -most are based on the DES block cipher, -and predate the arrival of the :ref:`modular crypt format <modular-crypt-format>`. -There are all considered insecure (at best), but may be useful when reading +All of the following hashes are/were used by various Unix flavors +to store user passwords; most are based on the DES block cipher, +and predate the arrival of the modular crypt format. +They should all be considered insecure at best, but may be useful when reading legacy password entries: .. toctree:: @@ -38,10 +60,12 @@ legacy password entries: passlib.hash.bigcrypt passlib.hash.crypt16 +.. _standard-unix-hashes: + Standard Unix Schemes --------------------- -All these schemes are currently used by various unix flavors to store user passwords. -They all follow the :ref:`modular crypt format <modular-crypt-format>` for encoding idenfiable hashes. +All these schemes are currently used by various Unix flavors to store user passwords. +They all follow the modular crypt format. .. toctree:: :maxdepth: 1 @@ -53,12 +77,11 @@ They all follow the :ref:`modular crypt format <modular-crypt-format>` for encod passlib.hash.sha256_crypt passlib.hash.sha512_crypt -Non-Standard Unix-Compatible Schemes ------------------------------------- -While most of these schemes are not commonly used by any unix flavor to store user passwords, -these are compatible with the :ref:`modular crypt format <modular-crypt-format>`, and can be -used in contexts which support them, in parallel with the others following -the modular crypt format. +Other Modular Crypt Schemes +--------------------------- +While most of these schemes are not (commonly) used by any Unix flavor to store user passwords, +these are compatible with the modular crypt format, and can be used +compatible by along side others in this section. .. toctree:: :maxdepth: 1 @@ -66,10 +89,72 @@ the modular crypt format. passlib.hash.apr_md5_crypt passlib.hash.phpass passlib.hash.nthash - passlib.hash.pbkdf2_digests + passlib.hash.pbkdf2_digest + passlib.hash.dlitz_pbkdf2_sha1 + +Special note should be made of the fallback helper, +which is not an actual hash scheme, but provides "disabled account" +behavior found in many Linux & BSD password files: + +.. toctree:: + :maxdepth: 1 + + passlib.hash.unix_fallback + +.. _ldap-hashes: + +LDAP / RFC2307 Hashes +===================== + +All of the following hashes use a variant of the password hash format +used by LDAPv2. Originally specified in :rfc:`2307` and used by OpenLDAP [#openldap]_, +the basic format ``{SCHEME}HASH`` has seen widespread adoption in a number of programs. + +.. _standard-ldap-hashes: + +Standard LDAP Schemes +--------------------- +.. toctree:: + :hidden: + + passlib.hash.ldap_std -Database Schemes ----------------- +The following schemes are explicitly defined by RFC 2307, +and are supported by OpenLDAP. + +* :class:`passlib.hash.ldap_md5` - MD5 digest +* :class:`passlib.hash.ldap_sha1` - SHA1 digest +* :class:`passlib.hash.ldap_salted_md5` - salted MD5 digest +* :class:`passlib.hash.ldap_salted_sha1` - salted SHA1 digest + +.. toctree:: + :maxdepth: 1 + + passlib.hash.ldap_crypt + +Also present is a special handler for LDAP plaintext passwords: + +* :class:`passlib.hash.ldap_plaintext` - LDAP-Aware Plaintext Handler + +Non-Standard LDAP Schemes +------------------------- +None of the following schemes are actually used by LDAP, +but follow the LDAP format: + +.. toctree:: + :maxdepth: 1 + + passlib.hash.atlassian_pbkdf2_sha1 + +.. + passlib.hash.roundup_plaintext + passlib.hash.ldap_hex_md5 + passlib.hash.ldap_hex_sha1 + +.. _database-hashes: + +Database Hashes +=============== The following schemes are used by various SQL databases to encode their own user accounts. These schemes have encoding and contextual requirements @@ -84,15 +169,22 @@ not seen outside those specific contexts: passlib.hash.oracle10 passlib.hash.oracle11 -Other Schemes -------------- +.. _other-hashes: + +Other Hashes +============ The following schemes are used in various contexts, -mainly for legacy compatibility purposes. +but have formats or uses which cannot be easily placed +in one of the above categories: .. toctree:: :maxdepth: 1 passlib.hash.hex_digests - passlib.hash.ldap_digests passlib.hash.plaintext - passlib.hash.unix_fallback + passlib.hash.grub_pbkdf2_sha512 + +References +========== + +.. [#openldap] OpenLDAP homepage - `<http://www.openldap.org/>`_. diff --git a/docs/lib/passlib.hosts.rst b/docs/lib/passlib.hosts.rst index 9f8e280..163e1e6 100644 --- a/docs/lib/passlib.hosts.rst +++ b/docs/lib/passlib.hosts.rst @@ -16,32 +16,15 @@ their use is oriented primarily towards Linux and BSD variants. Unix Password Hashes ==================== - -Supported Schemes ------------------ PassLib provides a number of pre-configured :class:`!CryptContext` instances which can identify and manipulate all the formats used by Linux and BSD. -The following chart lists the various operating systems, which -hash algorithms are known to be supported, as well as the hash's -identifying prefix (see the :ref:`modular crypt format <modular-crypt-format>`). - -==================================== ========== =========== =========== =========== =========== -Scheme Prefix Linux FreeBSD NetBSD OpenBSD -==================================== ========== =========== =========== =========== =========== -:class:`~passlib.hash.nthash` ``$3$`` y -:class:`~passlib.hash.des_crypt` n/a y y y y -:class:`~passlib.hash.bsdi_crypt` ``_`` y y -:class:`~passlib.hash.md5_crypt` ``$1$`` y y y y -:class:`~passlib.hash.bcrypt` ``$2a$`` y y y -:class:`~passlib.hash.sha1_crypt` ``$sha1$`` y -:class:`~passlib.hash.sha256_crypt` ``$5$`` y -:class:`~passlib.hash.sha512_crypt` ``$6$`` y -==================================== ========== =========== =========== =========== =========== +See the :ref:`modular crypt identifier list <mcf-identifiers>` for a complete +list of which hashes are supported by which operating system. Predefined Contexts ------------------- PassLib provides :class:`!CryptContext` instances -for the following Unix variants listed in `supported schemes`_: +for the following Unix variants: .. data:: linux_context @@ -116,97 +99,6 @@ Current Host OS In version 1.3 and earlier, it was available on non-Unix systems, though it did nothing useful. -.. _modular-crypt-format: -.. rst-class:: html-toggle - -Modular Crypt Format --------------------- - -Historically, most unix systems supported only :class:`~passlib.hash.des_crypt`. -Around the same time, many incompatible variations were also developed, -but their hashes were not easily distingiushable from each other -(see :ref:`archaic-unix-schemes`); making it impossible to use -multiple hashes on one system, or progressively migrate to a newer scheme. - -This was solved with the advent of the *Modular Crypt Format*, -introduced around the time that :class:`~passlib.hash.md5_crypt` was developed. -This format allows hashs from multiple schemes to exist within the same -database, by requiring that all hash strings begin with a unique prefix -using the format :samp:`${identifier}$`. - -Unfortunately, there is no specification document for this format. -Instead, it exists in *de facto* form only; the following -is an attempt to roughly identify the guidelines followed -by the modular crypt format hashes: - -1. Hash strings must use only 7-bit ascii characters. - - This is not strictly enforced at all; - for example Linux will accept 8-bit characters - within hash salt strings. However, **no** known - system generates hashes violating this rule; - and no such test vectors exist either, - so it can probably be assumed to be a case - of "permissive in what you accept, strict in what you generate". - -2. Hash strings should always start with the prefix :samp:`${identifier}$`, - where :samp:`{identifier}` is a short string uniquely identifying - hashes generated by that algorithm, using only lower case ascii - letters, numbers, and hyphens. - - Initially, most schemes adhereing to this format - only used a single digit to identify the hash - (eg ``$1$`` for :class:`!md5_crypt`). - Because of this, many systems only look at the first - character when attempting to distinguish hashes. - - Despite this, as Unix systems have branched off, - new hashes have been developed which used larger - identifying strings (eg ``$sha1$`` for :class:`sha1_crypt`); - so in general identifier strings should not be assumed to use a single character. - -3. Aside from the prefix, hashes should contain only ascii letters, - ascii numbers, and the characters in ``./``; though ``$`` - may be used as an internal field separator. - - This is the least adhered-to of any modular crypt format rule. - Other characters (such as ``=``, ``,``) are sometimes - used by various formats. - - The only hard and fast stricture - is that ``:`` and non-printable characters be avoided, - since this would interfere with parsing of /etc/passwd - where these hashes are typically stored. - - Pretty much all modular-crypt-format hashes - use ascii letters, numbers, ``.``, and ``/`` - to provide base64 encoding of their raw data, - though the exact character value assignments vary between hashes - (see :mod:`passlib.utils.h64`). - -4. Hash schemes should put their "checksum" portion - at the end of the hash, preferrably separated - by a ``$``. - - This allows password hashes to be easily truncated - to a "configuration string" containing just - the identifying prefix, rounds, salt, etc. - - This string then encodes all the information - generated needed to generate a new hash - in order to verify a password, without - having to perform excessive parsing. - - Most modular crypt format hashes follow this, - though some (like :class:`~passlib.hash.bcrypt`) omit the ``$`` separator. - -.. note:: - - All of the above is guesswork based on examination of existing - hashes and OS implementations; and was written merely - to clarify the issue of what the "modular crypt format" is. - It is drawn from no authoritative sources. - References ========== diff --git a/docs/lib/passlib.registry.rst b/docs/lib/passlib.registry.rst index 2d7a8a4..02efd91 100644 --- a/docs/lib/passlib.registry.rst +++ b/docs/lib/passlib.registry.rst @@ -21,11 +21,11 @@ Interface .. note:: - All password hashes registered with passlib are exposed as objects - importable from :mod:`passlib.hash`. This is true not just of the builtin - classes, but ones that are registered using the functions below. - The :mod:`!passlib.hash` module acts as a proxy object for this registry, - changes made here will affect it as well. + All password hashes registered with passlib + can be imported by name from the :mod:`passlib.hash` module. + This is true just just of the built-in hashes, + but for any hash registered with the registration functions + in this module. Usage ===== diff --git a/docs/modular_crypt_format.rst b/docs/modular_crypt_format.rst new file mode 100644 index 0000000..21b2053 --- /dev/null +++ b/docs/modular_crypt_format.rst @@ -0,0 +1,144 @@ +.. index:: modular crypt format + +.. _modular-crypt-format: + +.. rst-class:: html-toggle + +==================== +Modular Crypt Format +==================== + +.. centered:: *or*, a side note about a standard that isn't + +In short, the modular crypt format (MCF) is a standard +for encoding password hash strings, which requires hashes +have the format :samp:`${identifier}${content}`; where +:samp:`{identifier}` is an short alphanumeric string uniquely +identifying a particular scheme, and :samp:`{content}` +is the contents of the scheme, using only the characters +``[a-zA-Z0-9./]``. + +However, there appears to be no actual rules, specification document, +or central registry of identifiers; so the modular +crypt format is more of an ad-hoc idea than a true standard. + +History +======= +Historically, most unix systems supported only :class:`~passlib.hash.des_crypt`. +Around the same time, many incompatible variations were also developed, +but their hashes were not easily distingiushable from each other +(see :ref:`archaic-unix-schemes`); making it impossible to use +multiple hashes on one system, or progressively migrate to a newer scheme. + +This was solved with the advent of the MCF, +which was introduced around the time that :class:`~passlib.hash.md5_crypt` was developed. +This format allows hashes from multiple schemes to exist within the same +database, by requiring that all hash strings begin with a unique prefix +using the format :samp:`${identifier}$`. + +Requirements +============ +Unfortunately, there is no specification document for this format. +Instead, it exists in *de facto* form only; the following +is an attempt to roughly identify the guidelines followed +by the modular crypt format hashes found in passlib: + +1. Hash strings must use only 7-bit ascii characters. + + This is not strictly enforced at all; + for example Linux will accept 8-bit characters + within hash salt strings. However, **no** known + system generates hashes violating this rule; + and no such test vectors exist either, + so it can probably be assumed to be a case + of "permissive in what you accept, strict in what you generate". + +2. Hash strings should always start with the prefix :samp:`${identifier}$`, + where :samp:`{identifier}` is a short string uniquely identifying + hashes generated by that algorithm, using only lower case ascii + letters, numbers, and hyphens. + + Initially, most schemes adhereing to this format + only used a single digit to identify the hash + (eg ``$1$`` for :class:`!md5_crypt`). + Because of this, many systems only look at the first + character when attempting to distinguish hashes. + + Despite this, as Unix systems have branched off, + new hashes have been developed which used larger + identifying strings (eg ``$sha1$`` for :class:`sha1_crypt`); + so in general identifier strings should not be assumed to use a single character. + +3. Aside from the prefix, hashes should contain only ascii letters, + ascii numbers, and the characters in ``./``; though ``$`` + may be used as an internal field separator. + + This is the least adhered-to of any modular crypt format rule. + Other characters (such as ``=``, ``,``) are sometimes + used by various formats. + + The only hard and fast stricture + is that ``:`` and non-printable characters be avoided, + since this would interfere with parsing of /etc/passwd + where these hashes are typically stored. + + Pretty much all modular-crypt-format hashes + use ascii letters, numbers, ``.``, and ``/`` + to provide base64 encoding of their raw data, + though the exact character value assignments vary between hashes + (see :mod:`passlib.utils.h64`). + +4. Hash schemes should put their "checksum" portion + at the end of the hash, preferrably separated + by a ``$``. + + This allows password hashes to be easily truncated + to a "configuration string" containing just + the identifying prefix, rounds, salt, etc. + + This string then encodes all the information + generated needed to generate a new hash + in order to verify a password, without + having to perform excessive parsing. + + Most modular crypt format hashes follow this, + though some (like :class:`~passlib.hash.bcrypt`) omit the ``$`` separator. + +.. note:: + + All of the above is guesswork based on examination of existing + hashes and OS implementations; and was written merely + to clarify the issue of what the "modular crypt format" is. + It is drawn from no authoritative sources. + +.. _mcf-identifiers: + +Identifiers & Platform Support +============================== + +The following chart lists the various operating systems, which +hash algorithms are known to be supported, as well as the hash's +identifying prefix. + +==================================== ================== =========== =========== =========== =========== +Scheme Prefix Linux FreeBSD NetBSD OpenBSD +==================================== ================== =========== =========== =========== =========== +:class:`~passlib.hash.nthash` ``$3$`` y +:class:`~passlib.hash.des_crypt` n/a y y y y +:class:`~passlib.hash.bsdi_crypt` ``_`` y y +:class:`~passlib.hash.md5_crypt` ``$1$`` y y y y +:class:`~passlib.hash.sun_md5_crypt` ``$md5$`` +:class:`~passlib.hash.bcrypt` ``$2$``, ``$2a$`` y y y +:class:`~passlib.hash.sha1_crypt` ``$sha1$`` y +:class:`~passlib.hash.sha256_crypt` ``$5$`` y +:class:`~passlib.hash.sha512_crypt` ``$6$`` y +==================================== ================== =========== =========== =========== =========== + +.. note:: + + :class:`!des_crypt` and :class:`!bsdi_crypt` do not conform to the MCF, + but are listed here for completeness. + +.. todo:: + + include Solaris and other Unix flavors in this chart. diff --git a/docs/overview.rst b/docs/overview.rst index 3e62714..a6e91e0 100644 --- a/docs/overview.rst +++ b/docs/overview.rst @@ -13,7 +13,7 @@ Password Hash Schemes All of the hash schemes supported by passlib are implemented as classes importable from the :mod:`passlib.hash` module. All of these classes support a single uniform interface of standard class methods. -These methods are documented in detail by next section, the :doc:`password hash api <password_hash_api>`. +These methods are documented in detail by the :ref:`password hash api <password-hash-api>`. As a quick example of how a password hash can be used directly:: @@ -99,11 +99,7 @@ A quick example of how a password context can be used:: Utility Functions ================= -The :mod:`passlib.utils` module contains a large number +The :mod:`passlib.registry` and :mod:`passlib.utils` modules contain a large number of support functions, most of which are only needed when are implementing custom password hash schemes. Most users of passlib -will not need to use this subpackage. - -.. todo:: - - Add documentation showing how to create custom password hash handlers. +will not need to use these. diff --git a/docs/password_hash_api.rst b/docs/password_hash_api.rst index c450c41..e5eb59b 100644 --- a/docs/password_hash_api.rst +++ b/docs/password_hash_api.rst @@ -2,6 +2,8 @@ single: password hash api pair: custom hash handler; requirements +.. currentmodule:: passlib.hash + .. _password-hash-api: ================= @@ -13,27 +15,30 @@ Overview All of the hashes supported by PassLib are implemented using classes which support an identical interface; this document describes that interface in terms of a non-existent abstract class called :class:`!PasswordHash`. -All of the :doc:`supported password hashes <lib/passlib.hash>` -expose (at a minimum) the following methods and attributes: +All of the supported password hashes [#supported]_ expose (at a minimum) the following: + +:ref:`required-attributes` -The `required informational attributes`_ These consist of the attributes :attr:`~PasswordHash.name`, :attr:`~PasswordHash.setting_kwds`, and :attr:`~PasswordHash.context_kwds`. They permit users and applications to detect what features a specific :class:`!PasswordHash` allows and/or requires. -The `application interface`_ +:ref:`application-methods` + This interface consists of the :meth:`~PasswordHash.encrypt`, :meth:`~PasswordHash.identify`, and :meth:`~PasswordHash.verify` classmethods. - Most applications will only need to make use of these methods. + These are the methods most applications will need to make use of. + +:ref:`crypt-methods` -The `crypt interface`_ This interface consists of the :meth:`~PasswordHash.genconfig` and :meth:`~PasswordHash.genhash` classmethods. This mimics the standard unix crypt interface, - but is not usually needed by applications. + and are not usually needed by applications. + +:ref:`optional-attributes` -The `optional informational attributes`_ These attributes provide additional information about the capabilities and limitations of certain password hash schemes. @@ -73,9 +78,9 @@ passwords:: >>> sc.verify("wrongpassword", h) False -.. _required-informational-attributes: +.. _required-attributes: -Required Informational Attributes +Required Attributes ================================= .. attribute:: PasswordHash.name @@ -155,17 +160,17 @@ Required Informational Attributes If present, the class requires a username be specified whenever performing a hash calculation (eg: postgres_md5 and oracle10). -.. _application-interface: +.. _application-methods: -Application Interface -===================== +Application Methods +=================== The :meth:`~PasswordHash.encrypt`, :meth:`~PasswordHash.identify`, and :meth:`~PasswordHash.verify` methods are designed to provide an easy interface for applications. They allow encrypt new passwords without having to deal with details such as salt generation, verifying passwords without having to deal with hash comparison rules, and determining which scheme a hash belongs to when multiple schemes are in use. -.. classmethod:: PasswordHash.encrypt(secret, \*\*settings_and_context) +.. classmethod:: PasswordHash.encrypt(secret, \*\*settings_and_context_kwds) encrypt secret, returning resulting hash string. @@ -176,7 +181,7 @@ which scheme a hash belongs to when multiple schemes are in use. but the common case is to encode into utf-8 before processing. - :param settings_and_context: + :param settings_and_context_kwds: All other keywords are algorithm-specified, and should be listed in :attr:`~PasswordHash.setting_kwds` and :attr:`~PasswordHash.context_kwds`. @@ -185,10 +190,11 @@ which scheme a hash belongs to when multiple schemes are in use. :raises ValueError: * if settings are invalid and handler cannot correct them. - (eg: a provided salt contains invalid characters / length - causes an error, but an out of range rounds value is silently clipped). + (eg: if a ``salt`` string is to short, this will + cause an error; but a ``rounds`` value that's too large + should be silently clipped). - * if a context kwd contains an invalid value, or was required + * if a context keyword contains an invalid value, or was required but omitted. * if secret contains forbidden characters (e.g: des-crypt forbids null characters). @@ -219,7 +225,7 @@ which scheme a hash belongs to when multiple schemes are in use. Those that do will raise a ValueError once the hash is passed to :meth:`~PasswordHash.verify`. Most handlers, however, will just return ``False``. -.. classmethod:: PasswordHash.verify(secret, hash, \*\*context) +.. classmethod:: PasswordHash.verify(secret, hash, \*\*context_kwds) verify a secret against an existing hash. @@ -231,7 +237,7 @@ which scheme a hash belongs to when multiple schemes are in use. :param hash: A string containing the hash to check against. - :param context: + :param context_kwds: Any additional keywords will be passed to the encrypt method. These should be limited to those listed in :attr:`~PasswordHash.context_kwds`. @@ -246,11 +252,11 @@ which scheme a hash belongs to when multiple schemes are in use. :returns: ``True`` if the secret matches, otherwise ``False``. -.. _crypt-interface: +.. _crypt-methods: -Crypt Interface -=============== -While the primary interface is generally the most useful when integrating +Crypt Methods +============= +While the application methods are generally the most useful when integrating password support into an application, those methods are for the most part built on top of the crypt interface, which is somewhat simpler for *implementing* new password schemes. It also happens to match @@ -258,7 +264,7 @@ more closely with the crypt api of most unix systems, and consists of two functions: :meth:`~PasswordHash.genconfig()`` and :meth:`~PasswordHash.genhash()``. -.. classmethod:: PasswordHash.genconfig(\*\*settings) +.. classmethod:: PasswordHash.genconfig(\*\*settings_kwds) returns configuration string encoding settings for hash generation @@ -295,7 +301,7 @@ and :meth:`~PasswordHash.genhash()``. if the number of rounds is too small or too large, it should be clipped but accepted. - :param settings: + :param settings_kwds: this function takes in keywords as specified in :attr:`~PasswordHash.setting_kwds`. commonly supported keywords include ``salt`` and ``rounds``. @@ -309,7 +315,7 @@ and :meth:`~PasswordHash.genhash()``. :returns: the configuration string, or ``None`` if the algorithm does not support any configuration options. -.. classmethod:: PasswordHash.genhash(secret, config, \*\*context) +.. classmethod:: PasswordHash.genhash(secret, config, \*\*context_kwds) encrypt secret to hash @@ -324,7 +330,7 @@ and :meth:`~PasswordHash.genhash()``. returned by :meth:`~PasswordHash.genhash`, or a configuration string that was previously created by :meth:`~PasswordHash.genconfig`. - :param context: + :param context_kwds: All other keywords must be external contextual information required by the algorithm to create the hash. If any, these kwds must be specified in :attr:`~PasswordHash.context_kwds`. @@ -342,7 +348,9 @@ and :meth:`~PasswordHash.genhash()``. :returns: encoded hash matching specified secret, config, and context. -Optional Informational Attributes +.. _optional-attributes: + +Optional Attributes ================================= Many of the handlers in passlib expose the following informational attributes, though their presence is not uniform @@ -350,7 +358,8 @@ across all handlers in passlib. .. todo:: - could change these to be required if the appropriate setting kwd is used. + Consider making these attributes required for all hashes + which support the appropriate :attr:`settings` keyword. Rounds Information ------------------ @@ -427,6 +436,7 @@ the following attributes are usually exposed. for their salt keyword, how these attributes change in that situtation should be documentated. + .. not yet documentated, want to make sure this is how we want to do things: @@ -445,3 +455,8 @@ the following attributes are usually exposed. than are typically used. This field allows the full range to be accepted, while only a select subset to be used for generation. + +Footnotes +========= +.. [#supported] all supported password hashes, whether builtin or registered + from an external source can be found in the :mod:`passlib.hash` module. |
