aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2015-09-04 12:00:43 -0500
committerPaul Kehrer <paul.l.kehrer@gmail.com>2015-09-04 12:00:43 -0500
commit8359190f6e509fa2d12c0d86c9dfd1a8b35bf9cb (patch)
tree37436d6d1502532d40e78b3ea337cd084f59622e /docs
parent7402cf1c676ffb7ba48d6e90227bb4b1397af12d (diff)
parentcad58d7bfa1a01ade66828498dcb2894993838b9 (diff)
downloadcryptography-8359190f6e509fa2d12c0d86c9dfd1a8b35bf9cb.tar.gz
cryptography-8359190f6e509fa2d12c0d86c9dfd1a8b35bf9cb.tar.bz2
cryptography-8359190f6e509fa2d12c0d86c9dfd1a8b35bf9cb.zip
Merge branch 'master' into static-linking-osx
Diffstat (limited to 'docs')
-rw-r--r--docs/fernet.rst40
-rw-r--r--docs/spelling_wordlist.txt2
-rw-r--r--docs/x509/tutorial.rst15
3 files changed, 51 insertions, 6 deletions
diff --git a/docs/fernet.rst b/docs/fernet.rst
index 8ea33eef..a066ae63 100644
--- a/docs/fernet.rst
+++ b/docs/fernet.rst
@@ -106,6 +106,45 @@ 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 such as
+:class:`~cryptography.hazmat.primitives.kdf.pbkdf2.PBKDF2HMAC`, bcrypt or
+scrypt.
+
+.. code-block:: python
+
+ import base64
+ import os
+
+ from cryptography.fernet import Fernet
+ from cryptography.hazmat.backends import default_backend
+ from cryptography.hazmat.primitives import hashes
+ from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
+
+ 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 100,000 iterations which is what Django
+`recommends`_ in 2014.
+
Implementation
--------------
@@ -125,3 +164,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
diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt
index 1eed7c7a..75497840 100644
--- a/docs/spelling_wordlist.txt
+++ b/docs/spelling_wordlist.txt
@@ -1,6 +1,7 @@
affine
backend
backends
+bcrypt
Backends
Blowfish
boolean
@@ -22,6 +23,7 @@ deserialize
deserialized
Diffie
Docstrings
+Django
Encodings
fernet
Fernet
diff --git a/docs/x509/tutorial.rst b/docs/x509/tutorial.rst
index d1c8ba14..0fa061a2 100644
--- a/docs/x509/tutorial.rst
+++ b/docs/x509/tutorial.rst
@@ -67,13 +67,16 @@ a few details:
... x509.NameAttribute(NameOID.LOCALITY_NAME, u"San Francisco"),
... x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"My Company"),
... x509.NameAttribute(NameOID.COMMON_NAME, u"mysite.com"),
- ... ])).add_extension(x509.SubjectAlternativeName([
- ... # Describe what sites we want this certificate for.
- ... x509.DNSName(u"mysite.com"),
- ... x509.DNSName(u"www.mysite.com"),
- ... x509.DNSName(u"subdomain.mysite.com"),
+ ... ])).add_extension(
+ ... x509.SubjectAlternativeName([
+ ... # Describe what sites we want this certificate for.
+ ... x509.DNSName(u"mysite.com"),
+ ... x509.DNSName(u"www.mysite.com"),
+ ... x509.DNSName(u"subdomain.mysite.com"),
+ ... ]),
+ ... critical=False,
... # Sign the CSR with our private key.
- ... ])).sign(key, hashes.SHA256(), default_backend())
+ ... ).sign(key, hashes.SHA256(), default_backend())
>>> # Write our CSR out to disk.
>>> with open("path/to/csr.pem", "wb") as f:
... f.write(csr.public_bytes(serialization.Encoding.PEM))