summaryrefslogtreecommitdiff
path: root/docs/history/1.7.rst
blob: 449ee5600f56b0dfa71055f73e89e7153ee1174d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
===========
Passlib 1.7
===========

**1.7.1** (NOT YET RELEASED)
============================

.. py:currentmodule:: passlib.ifc

* bugfix: :meth:`PasswordHash.hash` will now warn if passed any settings
  keywords.  This usage was deprecated in 1.7.0, but warning wasn't properly enabled.
  See :ref:`hash-configuring` for the preferred way to pass settings.

* bugfix: setup.py: prevent erroneous version strings when run from an sdist.

.. rst-class:: emphasize-children toc-always-open

**1.7.0** (2016-11-22)
======================

Overview
--------

    *Welcome to Passlib 1.7!*

    This release includes a number of new features, cleans up
    some long-standing design issues, and contains a number of internal
    improvements; all part of the roadmap towards a leaner and simpler Passlib 2.0.

    *Highlights include:*

    * Support for :class:`~passlib.hash.argon2` and
      :class:`~passlib.hash.scrypt` hashes.

    * TOTP Two-Factor Authentications helpers in the :mod:`passlib.totp` module.

    .. currentmodule:: passlib.ifc

    * The misnamed :meth:`PasswordHash.encrypt` method has been renamed to  :meth:`PasswordHash.hash`
      (and the old alias deprecated).  This is part of a much
      larger project to clean up passlib's password hashing API,
      see the :ref:`hash-tutorial` for a walkthrough.

    * Large speedup of the internal PBKDF2 routines.

    * Updated documentation

Requirements
------------

   * **Passlib now requires Python 2.6, 2.7, or >= 3.3**.
     Support for Python versions 2.5 and 3.0 through 3.2 have been dropped.
     Support for PyPy 1.x has also been dropped.

   * The :mod:`passlib.ext.django` extension now requires Django 1.8 or better.
     Django 1.7 and earlier are no longer supported.

New Features
------------

*New Hashes*

    * :doc:`passlib.hash.argon2 </lib/passlib.hash.argon2>` --
      Support for the Argon2 password hash (:issue:`69`).

    * :doc:`passlib.hash.scrypt </lib/passlib.hash.scrypt>` --
      New password hash format which uses the SCrypt KDF (:issue:`8`).

    * :doc:`passlib.hash.cisco_asa </lib/passlib.hash.cisco_asa>` --
      Support for Cisco ASA 7.0 and newer hashes (:issue:`51`).
      *Note: this should be considered experimental, and needs verification
      of it's test vectors.*

*New Modules*

    * New :mod:`passlib.totp` module provides full support for TOTP tokens
      on both client and server side.  This module contains both low-level primitives,
      and high-level helpers for persisting and tracking client state.

    * New :mod:`passlib.pwd` module added to aid in password generation.
      Features support for alphanumeric passwords, or generation
      of phrases using the EFF's password generation wordlist.

*CryptContext Features*

    * The :class:`~passlib.context.CryptContext` object now has helper
      methods for dealing with hashes representing
      :ref:`disabled accounts <context-disabled-hashes>` (:issue:`45`).

    * The :class:`~passlib.context.CryptContext` object now supports
      a :ref:`harden_verify <context-harden-verify-option>` option,
      allowing applications to introduce a delay in verification
      to help prevent attackers discovering weak or missing hashes
      through timing attacks.

    * All hashers which truncate passwords (e.g. :class:`~passlib.hash.bcrypt`
      and :class:`~passlib.hash.des_crypt`) can now be configured to raise
      a :exc:`~passlib.exc.PasswordTruncateError` when a overly-large password is provided.
      This configurable via (for example) ``bcrypt.using(truncate_error=True).hash(secret)``,
      or globally as an option to CryptContext (:issue:`59`).

*Cryptographic Backends*

    * The :func:`~passlib.crypto.digest.pbkdf2_hmac` function and all PBKDF2-based
      hashes have been sped up by ~20% compared to Passlib 1.6. For an even greater
      speedup, it will now take advantage of the external `fastpbk2 <https://pypi.python.org/pypi/fastpbkdf2>`_
      library, or stdlib's :func:`hashlib.pbkdf2_hmac` (when available).

Other Changes
-------------

*Other changes of note in Passlib 1.7:*

    .. currentmodule:: passlib.ifc

    * New workflows have been for configuring the hashers through :meth:`PasswordHash.using`,
      and testing hashes through :meth:`PasswordHash.needs_update`.
      See the :ref:`hash-tutorial` for a walkthrough.

    * :class:`~passlib.hash.bcrypt` and :class:`~passlib.hash.bcrypt_sha256`
      now default to the "2b" format.

    * Added support for Django's Argon2 wrapper (:class:`~passlib.hash.django_argon2`)

    * :class:`passlib.apache.HtpasswdFile` has been updated to support all of Apache 2.4's
      hash schemes, as well as all host OS crypt formats; allowing for much more
      secure hashes in htpasswd files.

      You can now specify if the default hash should be compatible with apache 2.2 or 2.4, and host-specific or portable.
      See the ``default_schemes`` keyword for details.

    * Large parts of the documentation have been rewritten, to separate
      tutorial & api reference content, and provide more detail on various features.

    * Official documentation is now at https://passlib.readthedocs.io

*Internal Changes*

    .. currentmodule:: passlib.ifc

    * The majority of CryptContext's internal rounds handling & migration code has been
      moved to the password hashes themselves, taking advantage of the new :meth:`PasswordHash.using`
      and :meth:`PasswordHash.needs_update` methods.

      This allows much more flexibility when configuring a hasher directly,
      as well making it easier for CryptContext to support hash-specific parameters.

    * The shared :class:`!PasswordHash` unittests now check all hash handlers for
      basic thread-safety (motivated by the pybcrypt 0.2 concurrency bug).

    * :func:`~passlib.utils.consteq` is now wraps stdlib's :func:`hmac.compare_digest`
      when available (python 2.7.11, python 3.3 and up).

Bugfixes
--------
    * :class:`~passlib.hash.bcrypt`: Passlib will now detect and work around
      a fatal concurrency bug in py-bcrypt 0.2 and earlier
      (a :exc:`~passlib.exc.PasslibSecurityWarning` will also be issued).
      Nevertheless, users are *strongly* encouraged to upgrade to py-bcrypt 0.3
      or another bcrypt library if you are using the
      :doc:`bcrypt </lib/passlib.hash.bcrypt>` hash.

    * :class:`~passlib.CryptContext` instances now pass contextual keywords (such as `"user"`)
      to the hashes that support them, but ignore them for hashes that don't (:issue:`63`).

    * The :mod:`passlib.apache` htpasswd helpers now preserve blank lines and comments,
      rather than throwing a parse error (:issue:`73`).

    * :mod:`passlib.ext.django` and unittests: compatibility fixes for Django 1.9 / 1.10,
      and some internal refactoring (:issue:`68`).

    * The :class:`~passlib.hash.django_disabled` hash now appends
      a 40-char alphanumeric string, to match Django's behavior.

.. _encrypt-method-cleanup:

Deprecations
------------
As part of a long-range plan to restructure and simplify both the API and the internals of Passlib,
a number of methods have been deprecated & replaced.  The eventually goal is a large cleanup
and overhaul as part of Passlib 2.0. There will be at least one more 1.x version
before Passlib 2.0, to provide a final transitional release
(see the `Passlib Roadmap <https://bitbucket.org/ecollins/passlib/wiki/Roadmap>`_).

Password Hash API Deprecations
..............................
    .. currentmodule:: passlib.ifc

    As part of this cleanup, the :class:`~passlib.ifc.PasswordHash` API (used by all hashes in passlib),
    has had a number of changes:

    .. rst-class:: float-right

    .. seealso::

        :ref:`hash-tutorial`, which walks through using the new hasher interface.

    * **[major]** The :meth:`!PasswordHash.encrypt` method
      has been renamed to :meth:`PasswordHash.hash`,
      to clarify that it's performing one-way hashing rather than reversiable encryption.
      A compatibility alias will remain in place until Passlib 2.0.
      This should fix the longstanding :issue:`21`.

    * **[major]** Passing explicit configuration options to the :meth:`!PasswordHash.encrypt` method
      (now called :meth:`PasswordHash.hash`) is deprecated.
      To provide settings such as ``rounds`` and ``salt_size``, callers
      should use the new :meth:`PasswordHash.using`
      method, which generates a new hasher with a customized configuration.
      For example, instead of::

        >>>  sha256_crypt.encrypt("secret", rounds=12345)

      ... applications should now use::

        >>>  sha256_crypt.using(rounds=12345).hash("secret")

      Support for the old syntax will be removed in Passlib 2.0.

      .. note::

         This doesn't apply to contextual options such as :class:`~passlib.hash.cisco_pix`'s
         ``user`` keyword, which should still be passed into the :meth:`!hash` method.

    * **[minor]** The little-used :meth:`PasswordHash.genhash` and
      :meth:`PasswordHash.genconfig` methods have been deprecated.
      Compatibility aliases will remain in place until Passlib 2.0,
      at which point they will be removed entirely.

Crypt Context API Deprecations
..............................
    .. currentmodule:: passlib.context

    Applications which use passlib's :class:`~passlib.context.CryptContext` should not be
    greatly affected by this release; only one major deprecation was made:

    * **[major]** To match the :class:`!PasswordHash` API changes above,
      the :meth:`!CryptContext.encrypt` method was renamed to :meth:`CryptContext.hash`.
      A compatibility alias will remain until Passlib 2.0.

    A fewer internal options and infrequently used features have been deprecated:

    * **[minor]** :meth:`CryptContext.hash`, :meth:`~CryptContext.verify`,
      :meth:`~CryptContext.verify_and_update`, and
      :meth:`~CryptContext.needs_update`:
      The ``scheme`` keyword is now deprecated; support will be removed in Passlib 2.0.

    * **[minor]** :meth:`CryptContext.hash`: Passing
      settings keywords to :meth:`!hash` such as ``rounds`` and ``salt`` is deprecated.
      Code should now get ahold of the default hasher, and invoke it explicitly::

        >>>  # for example, calls that did this:
        >>>  context.hash(secret, rounds=1234)

        >>>  # should use this instead:
        >>>  context.handler().using(rounds=1234).hash(secret)

    * **[minor]** The ``vary_rounds`` option has been deprecated,
      and will be removed in Passlib 2.0.  It provided very little security benefit,
      and was judged not worth the additional code complexity it requires.

    * **[minor]** The special wildcard ``all`` scheme name
      has been deprecated, and will be removed in Passlib 2.0.  The only legitimate use
      was to support ``vary_rounds``, which itself will be removed in 2.0.

Other Deprecations
..................
    A few other assorted deprecations have been made:

    * The :func:`passlib.utils.generate_secret` function has been deprecated
      in favor of the new :mod:`passlib.pwd` module, and the old function will be removed
      in Passlib 2.0.

    * Most of passlib's internal cryptography helpers have been moved from
      :mod:`passlib.utils` to :mod:`passlib.crypto`, and the APIs refactored.
      This allowed unification of various hash management routines,
      some speed ups to the HMAC and PBKDF2 primitives, and opens up the architecture
      to support more optional backend libraries.

      Compatibility wrappers will be kept in place at the old location until Passlib 2.0.

    * Some deprecations and internal changes have been made to the :mod:`passlib.utils.handlers`
      module, which provides the common framework Passlib uses to implement hashers.

    .. caution::

      More backwards-incompatible relocations are planned for the internal
      :mod:`!passlib.utils` module in the Passlib 1.8 / 1.9 releases.

Backwards Incompatibilities
---------------------------
Changes in existing behavior:

    * **[minor]** M2Crypto no longer used to accelerate pbkdf2-hmac-sha1; applications relying on this
      to speed up :class:`~passlib.hash.pbkdf2_sha1` should install
      `fastpbkdf2 <https://pypi.python.org/pypi/fastpbkdf2>`_.

Scheduled removal of features:

    * **[minor]** :mod:`passlib.context`: The ``min_verify_time`` keyword
      that was deprecated in release 1.6, is now completely ignored.
      Support will be removed entirely in release 1.8.
      See the new :ref:`harden_verify <context-harden-verify-option>` keyword
      that replaces it.

    * **[trivial]** :mod:`passlib.hash`: The internal :meth:`!PasswordHash.parse_rounds` method, deprecated in 1.6, has been removed.

Minor incompatibilities:

    * **[minor]** :mod:`passlib.hash`: The little-used method :meth:`~passlib.ifc.PasswordHash.genconfig`
      will now always return a valid hash, rather than a truncated configuration
      string or ``None``.

    * **[minor]** :mod:`passlib.hash`: The little-used method :meth:`~passlib.ifc.PasswordHash.genhash` no longer accepts
      ``None`` as a config argument.

    * **[trivial]** :func:`passlib.utils.pbkdf2.pbkdf2` no longer supports custom PRF callables.
      this was an unused feature, and prevented some useful optimizations.