From b964a5cfb006229c1cdb1a4cf97df845ef5e754e Mon Sep 17 00:00:00 2001 From: Terry Chia Date: Sat, 29 Aug 2015 18:53:47 +0800 Subject: Add some text regarding using passwords with Fernet. --- docs/fernet.rst | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/docs/fernet.rst b/docs/fernet.rst index 8ea33eef..b6ee87f7 100644 --- a/docs/fernet.rst +++ b/docs/fernet.rst @@ -106,6 +106,43 @@ has support for implementing key rotation via :class:`MultiFernet`. See :meth:`Fernet.decrypt` for more information. + +Using passwords with Fernet +--------------------------- + +It is possible to use passwords with Fernet. To do this, you need to run the +password through a key derivation function like +:class:`~cryptography.hazmat.primitives.kdf.PBKDF2`: + +.. code-block:: python + + import base64 + import os + from cryptography.hazmat.primitives import hashes + from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC + from cryptography.hazmat.backends import default_backend + from cryptography.fernet import Fernet + + password = b"password" + salt = os.urandom(16) + + kdf = PBKDF2HMAC( + algorithm=hashes.SHA256(), + length=32, + salt=salt, + iterations=100000, + backend=default_backend + ) + key = base64.urlsafe_b64encode(kdf.derive(password)) + f = Fernet(key) + +In this scheme, the salt has to be stored in a retrievable location in order +to derive the same key from the password in the future. + +The iteration count used should be adjusted to be as high as your server can +tolerate. A good default is at least 100k iterations which is what Django +`recommends`_. + Implementation -------------- @@ -125,3 +162,4 @@ For complete details consult the `specification`_. .. _`Fernet`: https://github.com/fernet/spec/ .. _`specification`: https://github.com/fernet/spec/blob/master/Spec.md +.. _`recommends`_: https://github.com/django/django/blob/master/django/utils/crypto.py#L148 -- cgit v1.2.3