From af6f9900647c36224130270dab385d323ff7534d Mon Sep 17 00:00:00 2001 From: Chris Wolfe Date: Wed, 18 Oct 2017 14:23:53 -0500 Subject: Add Multifernet.rotate method (#3979) * add rotate method * add some more tests for the failure modes * start adding some documentation for the rotate method * operate on a single token at a time, leave lists to the caller * add versionadded add versionadded, drop rotate from class doctest * give rotate a doctest * single level, not aligned * add changelog for mf.rotate * show that, once rotated, the old fernet instance can no longer decrypt the token * add the instead of just the how * update docs to reflect removal of ttl from rotate * update tests * refactor internal methods so that we can extract the timestamp * implement rotate * update wordlist (case sensitive?) * lints * consistent naming * get_token_data/get_unverified_token_data -> better name * doc changes * use the static method, do not treat as imethod * move up to MultiFernet docs * add to authors * alter wording * monkeypatch time to make it less possible for the test to pass simply due to calls occuring in less than one second * set the time after encryption to make sure that the time is preserved as part of re-encryption --- docs/fernet.rst | 47 +++++++++++++++++++++++++++++++++++++++++++++- docs/spelling_wordlist.txt | 1 + 2 files changed, 47 insertions(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/fernet.rst b/docs/fernet.rst index 82d94faf..a0ffe64f 100644 --- a/docs/fernet.rst +++ b/docs/fernet.rst @@ -86,7 +86,8 @@ has support for implementing key rotation via :class:`MultiFernet`. .. versionadded:: 0.7 This class implements key rotation for Fernet. It takes a ``list`` of - :class:`Fernet` instances, and implements the same API: + :class:`Fernet` instances and implements the same API with the exception + of one additional method: :meth:`MultiFernet.rotate`: .. doctest:: @@ -109,6 +110,50 @@ has support for implementing key rotation via :class:`MultiFernet`. the front of the list to start encrypting new messages, and remove old keys as they are no longer needed. + Token rotation as offered by :meth:`MultiFernet.rotate` is a best practice + and manner of cryptographic hygiene designed to limit damage in the event of + an undetected event and to increase the difficulty of attacks. For example, + if an employee who had access to your company's fernet keys leaves, you'll + want to generate new fernet key, rotate all of the tokens currently deployed + using that new key, and then retire the old fernet key(s) to which the + employee had access. + + .. method:: rotate(msg) + + .. versionadded:: 2.2 + + Rotates a token by re-encrypting it under the :class:`MultiFernet` + instance's primary key. This preserves the timestamp that was originally + saved with the token. If a token has successfully been rotated then the + rotated token will be returned. If rotation fails this will raise an + exception. + + .. doctest:: + + >>> from cryptography.fernet import Fernet, MultiFernet + >>> key1 = Fernet(Fernet.generate_key()) + >>> key2 = Fernet(Fernet.generate_key()) + >>> f = MultiFernet([key1, key2]) + >>> token = f.encrypt(b"Secret message!") + >>> token + '...' + >>> f.decrypt(token) + 'Secret message!' + >>> key3 = Fernet(Fernet.generate_key()) + >>> f2 = MultiFernet([key3, key1, key2]) + >>> rotated = f2.rotate(token) + >>> f2.decrypt(rotated) + 'Secret message!' + + :param bytes msg: The token to re-encrypt. + :returns bytes: A secure message that cannot be read or altered without + the key. This is URL-safe base64-encoded. This is referred to as a + "Fernet token". + :raises cryptography.fernet.InvalidToken: If a ``token`` is in any + way invalid this exception is raised. + :raises TypeError: This exception is raised if the ``msg`` is not + ``bytes``. + .. class:: InvalidToken diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt index c53cc80f..4cf31f53 100644 --- a/docs/spelling_wordlist.txt +++ b/docs/spelling_wordlist.txt @@ -21,6 +21,7 @@ cryptographic cryptographically Debian decrypt +decrypts Decrypts decrypted decrypting -- cgit v1.2.3