summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Collins <elic@assurancetechnologies.com>2012-08-02 13:47:22 -0400
committerEli Collins <elic@assurancetechnologies.com>2012-08-02 13:47:22 -0400
commitcbd6cf1639ca34bf57046269d09bfc080a2e177a (patch)
tree097654693321d887215a95001c920dd3db9c4650
parentd6e0265ff8c082c1bed42c5de5fcc403d3ff6913 (diff)
downloadpasslib-cbd6cf1639ca34bf57046269d09bfc080a2e177a.tar.gz
bcrypt documentation updates - changed pybcrypt url, added details re: builtin-bcrypt implementation
-rw-r--r--CHANGES4
-rw-r--r--docs/install.rst2
-rw-r--r--docs/lib/passlib.hash.bcrypt.rst62
-rw-r--r--docs/new_app_quickstart.rst7
-rw-r--r--docs/password_hash_api.rst7
-rw-r--r--passlib/handlers/bcrypt.py6
6 files changed, 49 insertions, 39 deletions
diff --git a/CHANGES b/CHANGES
index 464c0eb..dde2429 100644
--- a/CHANGES
+++ b/CHANGES
@@ -319,13 +319,13 @@ Internal Changes
* deprecated some unused support functions within :mod:`!passlib.utils`,
they will be removed in release 1.7.
+.. _bcrypt-padding-issue:
+
**1.5.3** (2011-10-08)
======================
Bugfix release -- fixes BCrypt padding/verification issue (:issue:`25`)
- .. _bcrypt-padding-issue:
-
This release fixes a single issue with Passlib's BCrypt support: Many
BCrypt hashes generated by Passlib (<= 1.5.2) will not successfully verify
under some of the other BCrypt implementations, such as OpenBSD's
diff --git a/docs/install.rst b/docs/install.rst
index 0f98cc9..c4b728c 100644
--- a/docs/install.rst
+++ b/docs/install.rst
@@ -23,7 +23,7 @@ Google App Engine is supported as well.
Optional Libraries
==================
-* `py-bcrypt <http://www.mindrot.org/projects/py-bcrypt/>`_ or
+* `py-bcrypt <http://code.google.com/p/py-bcrypt/>`_ or
`bcryptor <https://bitbucket.org/ares/bcryptor/overview>`_
If either of these packages are installed, they will be used to provide
diff --git a/docs/lib/passlib.hash.bcrypt.rst b/docs/lib/passlib.hash.bcrypt.rst
index 1a2cce7..45eda31 100644
--- a/docs/lib/passlib.hash.bcrypt.rst
+++ b/docs/lib/passlib.hash.bcrypt.rst
@@ -30,9 +30,9 @@ for new applications. This class can be used directly as follows::
.. note::
- It is strongly recommended to install
- :ref:`py-bcrypt or bcryptor <optional-libraries>`
- if this algorithm is going to be used.
+ It is strongly recommended that you install
+ `py-bcrypt <http://code.google.com/p/py-bcrypt/>`_
+ when using this hash.
.. seealso:: the generic :ref:`PasswordHash usage examples <password-hash-examples>`
@@ -49,38 +49,43 @@ Interface
This class will use the first available of four possible backends:
- 1. `py-bcrypt <http://www.mindrot.org/projects/py-bcrypt/>`_, if installed.
+ 1. `py-bcrypt <http://code.google.com/p/py-bcrypt/>`_, if installed.
2. `bcryptor <https://bitbucket.org/ares/bcryptor/overview>`_, if installed.
3. stdlib's :func:`crypt.crypt()`, if the host OS supports BCrypt
(primarily BSD-derived systems).
- 4. A pure-python implementation of BCrypt, built into Passlib (disabled by default).
+ 4. A pure-python implementation of BCrypt, built into Passlib.
- It should be noted that the pure-python implementation (#4) is too slow
- to be useable, given the number of rounds currently required for security.
- Because of this, it is disabled by default, unless the environment variable
- ``PASSLIB_BUILTIN_BCRYPT="enabled"`` is set.
+ If no backends are available, :meth:`encrypt` and :meth:`verify`
+ will throw :exc:`~passlib.exc.MissingBackendError` when they are invoked.
+ You can check which backend is in use by calling :meth:`!bcrypt.get_backend()`.
- If the first three backends are not available, and the builtin
- backend has not been enabled, :meth:`encrypt` and :meth:`verify`
- will throw a :exc:`~passlib.exc.MissingBackendError` when they are called.
+.. warning::
+ The pure-python backend (#4) is disabled by default!
- You can see which backend is in use by calling the :meth:`get_backend()` method.
+ This backend is currently too slow to be usuable given the number of rounds required
+ for security. That said, if you have no other alternative and need to use it,
+ set the environmental variable ``PASSLIB_BUILTIN_BCRYPT="enabled"``
+ before importing Passlib.
-.. versionchanged:: 1.6
- The pure-python backend was added, though it's disabled by default
- for security. (speedups are welcome!)
+ In detail: Passlib's :ref:`rounds selection guidelines <rounds-selection-guidelines>`
+ currently require BCrypt be able to do >= 12 cost in <= 300ms. By this standard
+ the pure-python backend is 128x too slow under CPython 2.7, and 16x too slow under PyPy 1.8.
+ (speedups are welcome!)
Format & Algorithm
==================
Bcrypt is compatible with the :ref:`modular-crypt-format`, and uses ``$2$`` and ``$2a$`` as the identifying prefix
for all it's strings (``$2$`` is seen only for legacy hashes which used an older version of Bcrypt).
-An example hash (of ``password``) is ``$2a$12$GhvMmNVjRW29ulnudl.LbuAnUtN/LRfe1JsBm1Xu6LE3059z5Tr8m``.
+An example hash (of ``password``) is:
+
+ ``$2a$12$GhvMmNVjRW29ulnudl.LbuAnUtN/LRfe1JsBm1Xu6LE3059z5Tr8m``
+
Bcrypt hashes have the format :samp:`$2a${rounds}${salt}{checksum}`, where:
-* :samp:`{rounds}` is the cost parameter, encoded as 2 zero-padded decimal digits,
+* :samp:`{rounds}` is a cost parameter, encoded as 2 zero-padded decimal digits,
which determines the number of iterations used via :samp:`{iterations}=2**{rounds}` (rounds is 12 in the example).
-* :samp:`{salt}` is the 22 character salt string, using the characters in the regexp range ``[./A-Za-z0-9]`` (``GhvMmNVjRW29ulnudl.Lbu`` in the example).
-* :samp:`{checksum}` is the 31 character checksum, using the same characters as the salt (``AnUtN/LRfe1JsBm1Xu6LE3059z5Tr8m`` in the example).
+* :samp:`{salt}` is a 22 character salt string, using the characters in the regexp range ``[./A-Za-z0-9]`` (``GhvMmNVjRW29ulnudl.Lbu`` in the example).
+* :samp:`{checksum}` is a 31 character checksum, using the same characters as the salt (``AnUtN/LRfe1JsBm1Xu6LE3059z5Tr8m`` in the example).
While BCrypt's basic algorithm is described in it's design document [#f1]_,
the OpenBSD implementation [#f2]_ is considered the canonical reference, even
@@ -95,7 +100,7 @@ This implementation of bcrypt differs from others in a few ways:
BCrypt does not specify what the behavior should be when
passed a salt string outside of the regexp range ``[./A-Za-z0-9]``.
In order to avoid this situtation, Passlib strictly limits salts to the
- allowed character set, and will throw a ValueError if an invalid
+ allowed character set, and will throw a :exc:`ValueError` if an invalid
salt character is encountered.
* Unicode Policy:
@@ -118,10 +123,10 @@ This implementation of bcrypt differs from others in a few ways:
encoding only 2 bits of data, the remaining 4 are "padding" bits.
Similarly, the last character of the digest contains 4 bits of data,
and 2 padding bits. Because of the way they are coded, many BCrypt implementations
- will reject all passwords if these padding bits are not set to 0.
- Due to a legacy issue with Passlib <= 1.5.2,
- Passlib instead prints a warning if it encounters hashes with any padding bits set,
- and will then validate them correctly.
+ will reject *all* passwords if these padding bits are not set to 0.
+ Due to a legacy :ref:`issue <bcrypt-padding-issue>` with Passlib <= 1.5.2,
+ Passlib will print a warning if it encounters hashes with any padding bits set,
+ and then validate the hash as if the padding bits were cleared.
(This behavior will eventually be deprecated and such hashes
will throw a :exc:`ValueError` instead).
@@ -135,8 +140,8 @@ This implementation of bcrypt differs from others in a few ways:
in *crypt_blowfish* adding support for two new BCrypt hash identifiers:
``$2x$``, allowing sysadmins to mark any ``$2a$`` hashes which were potentially
- generated with the buggy algorithm. Passlib 1.6 recognizes, but does not
- currently support generating or verifying these hashes.
+ generated with the buggy algorithm. Passlib 1.6 recognizes (but does not
+ currently support generating or verifying) these hashes.
``$2y$``, the default for crypt_blowfish 1.1 and newer, indicates
the hash was generated with the canonical OpenBSD-compatible algorithm,
@@ -146,7 +151,8 @@ This implementation of bcrypt differs from others in a few ways:
As well, crypt_blowfish 1.2 modified the way it generates ``$2a$`` hashes,
so that passwords containing the byte value 0xFF are hashed in a manner
incompatible with either the buggy or canonical algorithms. Passlib
- does not support this variant either, though it should rarely be needed.
+ does not support this algorithmic variant either, though it should
+ be *very* rarely encountered in practice.
.. rubric:: Footnotes
diff --git a/docs/new_app_quickstart.rst b/docs/new_app_quickstart.rst
index 43b7631..96f793a 100644
--- a/docs/new_app_quickstart.rst
+++ b/docs/new_app_quickstart.rst
@@ -96,10 +96,9 @@ of simultaneous logon attempts (e.g. web apps).
.. note::
For BCrypt support on non-BSD systems,
- Passlib requires a C-extension module
- provided by the external
- :ref:`py-bcrypt or bcryptor <optional-libraries>` packages.
- Neither of these currently supports Python 3.
+ Passlib requires the C-extension provided by
+ `py-bcrypt <http://code.google.com/p/py-bcrypt/>`_.
+ (py-bcrypt does not currently support Python 3).
SHA512-Crypt
............
diff --git a/docs/password_hash_api.rst b/docs/password_hash_api.rst
index f97a327..19a2b8d 100644
--- a/docs/password_hash_api.rst
+++ b/docs/password_hash_api.rst
@@ -713,8 +713,10 @@ and the following attributes should be defined:
.. index:: rounds; choosing the right value
-Choosing the right ``rounds`` value
-===================================
+.. _rounds-selection-guidelines:
+
+Choosing the right rounds value
+===============================
Passlib's default rounds settings attempt to be secure enough for
the average [#avgsys]_ system. But the "right" value for a given hash
is dependant on the server, it's cpu, it's expected load, and it's users.
@@ -735,4 +737,3 @@ For this reason, it is strongly recommended to not use a value lower than Passli
.. [#avgsys] For Passlib 1.6, all hashes were retuned to take ~250ms on a
system with a 3 ghz 64 bit CPU.
-
diff --git a/passlib/handlers/bcrypt.py b/passlib/handlers/bcrypt.py
index 5b37dc9..0e76524 100644
--- a/passlib/handlers/bcrypt.py
+++ b/passlib/handlers/bcrypt.py
@@ -73,7 +73,8 @@ class bcrypt(uh.HasManyIdents, uh.HasRounds, uh.HasSalt, uh.HasManyBackends, uh.
:param rounds:
Optional number of rounds to use.
Defaults to 12, must be between 4 and 31, inclusive.
- This value is logarithmic, the actual number of iterations used will be :samp:`2**{rounds}`.
+ This value is logarithmic, the actual number of iterations used will be :samp:`2**{rounds}`
+ -- increasing the rounds by +1 will double the amount of time taken.
:type ident: str
:param ident:
@@ -101,6 +102,9 @@ class bcrypt(uh.HasManyIdents, uh.HasRounds, uh.HasSalt, uh.HasManyBackends, uh.
(but does not support) the broken ``"2x"`` hashes.
(see the :ref:`crypt_blowfish bug <crypt-blowfish-bug>`
for details).
+
+ .. versionchanged:: 1.6
+ Added a pure-python backend.
"""
#===================================================================