summaryrefslogtreecommitdiff
path: root/docs/password_hash_api.rst
diff options
context:
space:
mode:
authorEli Collins <elic@assurancetechnologies.com>2011-03-14 21:21:42 -0400
committerEli Collins <elic@assurancetechnologies.com>2011-03-14 21:21:42 -0400
commit1d0a05a785795bd85708d49c7dfa27fbaf4a03c7 (patch)
tree783d458aed2a4f31422eecff3949ddf7b5e5f307 /docs/password_hash_api.rst
parent5076cf146f56122ed712f17849dfbc782ca36e93 (diff)
downloadpasslib-1d0a05a785795bd85708d49c7dfa27fbaf4a03c7.tar.gz
documentation work
================== * finished password hash api description * various documentation cleanups * removed unused quickstart doc
Diffstat (limited to 'docs/password_hash_api.rst')
-rw-r--r--docs/password_hash_api.rst307
1 files changed, 185 insertions, 122 deletions
diff --git a/docs/password_hash_api.rst b/docs/password_hash_api.rst
index 97a6798..1c3f6ab 100644
--- a/docs/password_hash_api.rst
+++ b/docs/password_hash_api.rst
@@ -1,110 +1,157 @@
.. _password-hash-api:
-======================
+=================
Password Hash API
-======================
-
-Motivation
-==========
-Passlib supports many different password hashing schemes.
-A majority of them were originally designed to be used on a unix
-system, follow some variant of the unix ``crypt()`` api,
-and have are encoded using the :ref:`modular-crypt-format`.
-Others were designed for use specific contexts only,
-such as PostgreSQL.
-
-Passlib was designed to provide a uniform interface to implementations
-of all these schemes, as well as hide away as much of the implementation
-detail as possible; both in order to make it easier to integrate password hashing
-into new and existing applications. Because of these goals, some of the methods
-required by the crypt handler api tend to overlap slightly,
-in order to accomodate a wide variety of application requirements,
-and other parts have been kept intentionally non-commital, in order to allow
-flexibility of implementation.
-
-All of the schemes built into passlib implement this interface;
-most them as modules within the :mod:`passlib.hash` package.
+=================
Overview
========
-A handler which implements a password hash may be a module, class, or instance
-(though most of the ones builtin to Passlib are classes).
-The only requirement is that it expose a minimum of the following attributes
-and functions (for classes, the following functions must be static or class methods).
-
-All handlers have the following three attributes:
-
- * ``name`` - unique identifier used to distinguish scheme within
- * ``setting_kwds`` - list of settings recognized by ``genconfig()`` and ``encrypt()``.
- * ``context_kwds`` - list of context specified keywords required by algorithm
-
-All handlers have the following five functions:
-
- * ``encrypt(secret, **context_and_settings) -> hash`` - used for encrypting secret using specified options
- * ``identify(hash) -> True|False`` - used for identifying hash belonging to this algorithm
- * ``verify(secret, hash, **context)`` - used for verifying a secret against an existing hash
-
- * ``genconfig(**settings) -> configuration string`` - used for generating configuration strings.
- * ``genhash(secret, config, **context) -> hash`` - used for encrypting secret using configuration string or existing hash
-
-Usage Examples
-==============
-
-.. todo::
-
- show some quick examples using bcrypt.
-
-Informational Attributes
-========================
-.. attribute:: name
+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:
+
+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`_
+ This 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.
+
+The `crypt interface`_
+ This consists of the :meth:`~PasswordHash.genconfig`,
+ :meth:`~PasswordHash.genhash`. This mimics the standard unix crypt interface,
+ but is usually used directly by applications.
+
+The `optional informational attributes`_
+ These attributes provide additional information
+ about the capabilities and limitations of certain password hash schemes.
+
+Usage
+=====
+While most uses of PassLib are done through a :class:`~passlib.base.CryptContext` class,
+the various :class:`!PasswordHash` classes can be used directly to manipulate
+passwords:
+
+ >>> # for example, the SHA256-Crypt class:
+ >>> from passlib.hash import sha256_crypt as sc
+
+ >>> # using it to encrypt a password:
+ >>> h = sc.encrypt("password")
+ >>> h
+ '$5$rounds=40000$HIo6SCnVL9zqF8TK$y2sUnu13gp4cv0YgLQMW56PfQjWaTyiHjVbXTgleYG9'
+
+ >>> # subsequent calls to sc.encrypt() will generate a new salt:
+ >>> sc.encrypt("password")
+ '$5$rounds=40000$1JfxoiYM5Pxokyh8$ez8uV8jjXW7SjpaTg2vHJmx3Qn36uyZpjhyC9AfBi7B'
+
+ >>> # the same, but with an explict number of rounds:
+ >>> sc.encrypt("password", rounds=10000)
+ '$5$rounds=10000$UkvoKJb8BPrLnR.D$OrUnOdr.IJx74hmyyzuRdr5k9lSXdkFxKmr7bLQTty5'
+
+ >>> #the identify method can be used to determine the format of an unknown hash:
+ >>> sc.identify(h)
+ True
+
+ >>> #check if some other hash is recognized (in this case, an MD5-Crypt hash)
+ >>> sc.identify('$1$3azHgidD$SrJPt7B.9rekpmwJwtON31')
+ False
+
+ >>> #the verify method encapsulates all hash comparison logic for a class:
+ >>> sc.verify("password", h)
+ True
+ >>> sc.verify("wrongpassword", h)
+ False
+
+.. _required-informational-attributes:
+
+Required Informational Attributes
+=================================
+.. attribute:: PasswordHash.name
A unique name used to identify
- the particular algorithm this handler implements.
+ the particular scheme this class implements.
- These names should consist only of lowercase a-z, the digits 0-9, and hyphens.
+ These names should consist only of lowercase a-z, the digits 0-9, and underscores.
.. note::
- All handlers built into passlib are implemented as modules
- whose path corresponds to the name, with an underscore replacing the hyphen.
- For example, ``des-crypt`` is stored as the module ``passlib.hash.des_crypt``.
+ All handlers built into passlib are implemented as classes
+ located under :samp:`passlib.hash.{name}`, where :samp:`{name}`
+ is both the class name, and the value of the ``name`` attribute.
+ This is not a requirement, and may not be true for externally-defined handers.
-.. attribute:: setting_kwds
+.. attribute:: PasswordHash.setting_kwds
- If the algorithm supports per-hash configuration
+ If the scheme supports per-hash configuration
(such as salts, variable rounds, etc), this attribute
should contain a tuple of keywords corresponding
to each of those configuration options.
- This should correspond with the keywords accepted
- by :func:`genconfig`, see that method for details.
+ This should list all the main configuration keywords accepted
+ by :meth:`~PasswordHash.genconfig` and :meth:`~PasswordHash.encrypt`.
- If no settings are supported, this attribute
- is an empty tuple.
+ If no configuration options are supported, this attribute should be an empty tuple.
-.. attribute:: context_kwds
+ While each class may support a variety of options, each with their own meaning
+ and semantics, the following keywords should have the same behavior
+ across all schemes:
- Some algorithms require external contextual information
- in order to generate a checksum for a password.
- An example of this is Postgres' md5 algorithm,
- which requires the username to be provided
- (which it uses as a salt).
+ ``salt``
+ If present, this means the algorithm contains some number of bits of salt
+ which should vary with every new hash created.
+
+ Providing this as a keyword should allow the application to select
+ a specific salt string; though not only is this far from needed
+ for most cases, the salt string's content constraints vary for each algorithm.
+
+ ``rounds``
+ If present, this means the algorithm allows for a variable number of rounds
+ to be used, allowing the processor time required to be increased.
+
+ Providing this as a keyword should allow the application to
+ override the class' default number of rounds. While this
+ must be a non-negative integer for all implementations,
+ additional constraints may be present for each algorith
+ (such as the cost varying on a linear or logarithmic scale).
+
+ ``ident``
+ If present, the class supports multiple formats for encoding
+ the same hash. The class's documentation will generally list
+ the allowed values, allowing alternate output formats to be selected.
+
+.. attribute:: PasswordHash.context_kwds
This attribute should contain a tuple of keywords
which should be passed into :func:`encrypt`, :func:`verify`,
and :func:`genhash` in order to encrypt a password.
+ Some algorithms require external contextual information
+ in order to generate a checksum for a password.
+ An example of this is :doc:`Postgres' MD5 algorithm <lib/passlib.hash.postgres_md5>`,
+ which requires the username to be provided when generating a hash
+ (see that class for an example of how this works in pratice).
+
Since most password hashes require no external information,
- this tuple will usually be empty.
+ this tuple will usually be empty, and references
+ to context keywords can be ignored for all but a few classes.
-Primary Interface
-=================
-The ``encrypt()``, ``identify()``, and ``verify()`` methods are designed
-to provide an easy interface for applications to encrypt new passwords
-and verify existing passwords, without having to deal with details such
-as salt formats.
+.. _application-interface:
-.. function:: encrypt(secret, \*\*settings_and_context)
+Application Interface
+=====================
+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)
encrypt secret, returning resulting hash string.
@@ -115,12 +162,12 @@ as salt formats.
but the common case is to encode into utf-8
before processing.
- :param kwds:
+ :param settings_and_context:
All other keywords are algorithm-specified,
- and should be listed in :attr:`setting_kwds`
- and :attr:`context_kwds`.
+ and should be listed in :attr:`~PasswordHash.setting_kwds`
+ and :attr:`~PasswordHash.context_kwds`.
- Common keywords include ``salt`` and ``rounds``.
+ Common settings keywords include ``salt`` and ``rounds``.
:raises ValueError:
* if settings are invalid and not correctable.
@@ -134,9 +181,9 @@ as salt formats.
on the types of characters.
:returns:
- Hash encoded in algorithm-specified format.
+ Hash string, encoded in algorithm-specific format.
-.. function:: identify(hash)
+.. classmethod:: PasswordHash.identify(hash)
identify if a hash string belongs to this algorithm.
@@ -150,11 +197,12 @@ as salt formats.
* ``False`` if none of the above conditions was met.
.. note::
+
Some handlers may or may not return ``True`` for malformed hashes.
- Those that do will raise a ValueError once the hash is passed to :func:`verify`.
+ Those that do will raise a ValueError once the hash is passed to :meth:`~PasswordHash.verify`.
Most handlers, however, will just return ``False``.
-.. function:: verify(secret, hash, \*\*context)
+.. classmethod:: PasswordHash.verify(secret, hash, \*\*context)
verify a secret against an existing hash.
@@ -169,7 +217,7 @@ as salt formats.
:param context:
Any additional keywords will be passed to the encrypt
method. These should be limited to those listed
- in :attr:`context_kwds`.
+ in :attr:`~PasswordHash.context_kwds`.
:raises TypeError:
* if the secret is not a string.
@@ -177,21 +225,24 @@ as salt formats.
:raises ValueError:
* if the hash not specified
* if the hash does not match this algorithm's hash format
- * if the provided secret contains forbidden chars (see :func:`encrypt`)
+ * if the provided secret contains forbidden characters (see :meth:`~PasswordHash.encrypt`)
:returns:
``True`` if the secret matches, otherwise ``False``.
-Secondary Interface
-===================
+.. _crypt-interface:
+
+Crypt Interface
+===============
While the primary interface is generally the most useful when integrating
password support into an application, those methods are for the most part
-built on top of the secondary interface, which is somewhat simpler
+built on top of the crypt interface, which is somewhat simpler
for *implementing* new password schemes. It also happens to match
more closely with the crypt api of most unix systems,
-and consists of two functions: ``genconfig()`` and ``genhash``.
+and consists of two functions: :meth:`~PasswordHash.genconfig()``
+and :meth:`~PasswordHash.genhash()``.
-.. function:: genconfig(\*\*settings)
+.. classmethod:: PasswordHash.genconfig(\*\*settings)
returns configuration string encoding settings for hash generation
@@ -203,7 +254,7 @@ and consists of two functions: ``genconfig()`` and ``genhash``.
than just a salt).
This function takes in optional configuration options (a complete list
- of which should be found in :attr:`setting_kwds`), validates
+ of which should be found in :attr:`~PasswordHash.setting_kwds`), validates
the inputs, fills in defaults where appropriate, and returns
a configuration string.
@@ -229,7 +280,7 @@ and consists of two functions: ``genconfig()`` and ``genhash``.
be clipped but accepted.
:param settings:
- this function takes in keywords as specified in :attr:`setting_kwds`.
+ this function takes in keywords as specified in :attr:`~PasswordHash.setting_kwds`.
commonly supported keywords include ``salt`` and ``rounds``.
:raises ValueError:
@@ -242,7 +293,7 @@ and consists of two functions: ``genconfig()`` and ``genhash``.
:returns:
the configuration string, or ``None`` if the algorithm does not support any configuration options.
-.. function:: genhash(secret, config, \*\*context)
+.. classmethod:: PasswordHash.genhash(secret, config, \*\*context)
encrypt secret to hash
@@ -254,13 +305,13 @@ and consists of two functions: ``genconfig()`` and ``genhash``.
:arg config:
configuration string to use when encrypting secret.
this can either be an existing hash that was previously
- returned by :meth:`genhash`, or a configuration string
- that was previously created by :meth:`genconfig`.
+ returned by :meth:`~PasswordHash.genhash`, or a configuration string
+ that was previously created by :meth:`~PasswordHash.genconfig`.
:param context:
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:`context_kwds`.
+ these kwds must be specified in :attr:`~PasswordHash.context_kwds`.
:raises TypeError:
* if the configuration string is not provided
@@ -277,56 +328,68 @@ and consists of two functions: ``genconfig()`` and ``genhash``.
Optional Informational Attributes
=================================
Many of the handlers in passlib expose the following informational
-attributes, though their presence and meaning is not uniform
+attributes, though their presence is not uniform
across all handlers in passlib.
-For schemes which support a variable number of rounds,
-the following attributes are usually exposed
-(applications can test by checking for ``getattr(handler,"default_rounds",None)>0``):
+.. todo::
-.. attribute:: default_rounds
+ could change these to be required if the appropriate setting kwd is used.
+
+Rounds Information
+------------------
+For schemes which support a variable number of rounds (ie, ``'rounds' in PasswordHash.setting_kwds``),
+the following attributes are usually exposed.
+(Applications can test for this suites' presence by checking if ``getattr(handler,"max_rounds",None)>0``)
+
+.. attribute:: PasswordHash.default_rounds
The default number of rounds that will be used if not
- explicitly set when calling :func:`encrypt` or :func:`genconfig`.
+ explicitly set when calling :meth:`~PasswordHash.encrypt` or :meth:`~PasswordHash.genconfig`.
-.. attribute:: min_rounds
+.. attribute:: PasswordHash.min_rounds
The minimum number of rounds the scheme allows.
Specifying values below this will generally result
- in a warning, and ``min_rounds`` will be used instead.
+ in a warning, and :attr:`~!PasswordHash.min_rounds` will be used instead.
-.. attribute:: max_rounds
+.. attribute:: PasswordHash.max_rounds
The maximum number of rounds the scheme allows.
Specifying values above this will generally result
- in a warning, and ``max_rounds`` will be used instead.
+ in a warning, and :attr:`~!PasswordHash.max_rounds` will be used instead.
-.. attribute:: rounds_cost
+.. attribute:: PasswordHash.rounds_cost
Specifies how the rounds value affects the amount of time taken.
Currently used values are:
- ``linear`` - time taken scales linearly with rounds value (eg: sha512_crypt)
- ``log2`` - time taken scales exponentially with rounds value (eg: bcrypt)
+ ``linear``
+ time taken scales linearly with rounds value (eg: :class:`~passlib.hash.sha512_crypt`)
+
+ ``log2``
+ time taken scales exponentially with rounds value (eg: :class:`~passlib.hash.bcrypt`)
-For schemes which support a salt,
-the following attributes are usually exposed
-(applications can test by checking for ``getattr(handler,"max_salt_chars",None)>0``):
+Salt Information
+----------------
+For schemes which support a salt (ie, ``'salt' in PasswordHash.setting_kwds``),
+the following attributes are usually exposed.
+(Applications can test for this suites' presence by checking if ``getattr(handler,"max_salt_chars",None)>0``)
-.. attribute:: max_salt_chars
+.. attribute:: PasswordHash.max_salt_chars
maximum number of characters which will be *used*
- if a salt string is provided to :func:`genconfig` or :func:`encrypt`.
+ if a salt string is provided to :meth:`~PasswordHash.genconfig` or :meth:`~PasswordHash.encrypt`.
must be positive integer if salts are supported,
may be ``None`` or ``0`` if salts are not supported.
-.. attribute:: min_salt_chars
+.. attribute:: PasswordHash.min_salt_chars
minimum number of characters required in salt string,
- if provided to :func:`genconfig` or :func:`encrypt`.
- must be non-negative integer.
+ if provided to :meth:`~PasswordHash.genconfig` or :meth:`~PasswordHash.encrypt`.
+ must be non-negative integer that is not greater than :attr:`~PasswordHash.max_salt_chars`.
-.. attribute:: salt_charset
+.. attribute:: PasswordHash.salt_charset
string containing list of all characters which are allowed
- to be specified in salt parameter. usually `passlib.utils.h64.CHARS`.
+ to be specified in salt parameter.
+ for most hashes, this is equal to `passlib.utils.h64.CHARS`.