aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/changelog.rst7
-rw-r--r--docs/contributing.rst8
-rw-r--r--docs/exceptions.rst10
-rw-r--r--docs/fernet.rst17
-rw-r--r--docs/hazmat/backends/interfaces.rst49
-rw-r--r--docs/hazmat/backends/openssl.rst28
-rw-r--r--docs/hazmat/bindings/openssl.rst20
-rw-r--r--docs/hazmat/primitives/index.rst1
-rw-r--r--docs/hazmat/primitives/interfaces.rst172
-rw-r--r--docs/hazmat/primitives/key-derivation-functions.rst125
-rw-r--r--docs/index.rst11
-rw-r--r--docs/installation.rst74
12 files changed, 483 insertions, 39 deletions
diff --git a/docs/changelog.rst b/docs/changelog.rst
index 0a03c396..f401fe7c 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -6,10 +6,15 @@ Changelog
**In development**
-* Added :doc:`/hazmat/backends/commoncrypto` with hash and HMAC support.
+* Added :doc:`/hazmat/backends/commoncrypto`.
* Added initial :doc:`/hazmat/bindings/commoncrypto`.
* Removed ``register_cipher_adapter`` method from
:class:`~cryptography.hazmat.backends.interfaces.CipherBackend`.
+* Added support for the OpenSSL backend under Windows.
+* Improved thread-safety for the OpenSSL backend.
+* Fixed compilation on systems where OpenSSL's ``ec.h`` header is not
+ available, such as CentOS.
+* Added :class:`~cryptography.hazmat.primitives.kdf.pbkdf2.PBKDF2HMAC`.
0.1 - 2014-01-08
~~~~~~~~~~~~~~~~
diff --git a/docs/contributing.rst b/docs/contributing.rst
index 4bb1461d..184ba214 100644
--- a/docs/contributing.rst
+++ b/docs/contributing.rst
@@ -60,6 +60,12 @@ always indistinguishable. As a result ``cryptography`` has, as a design
philosophy: "make it hard to do insecure things". Here are a few strategies for
API design which should be both followed, and should inspire other API choices:
+If it is necessary to compare a user provided value with a computed value (for
+example, verifying a signature), there should be an API provided which performs
+the verification in a secure way (for example, using a constant time
+comparison), rather than requiring the user to perform the comparison
+themselves.
+
If it is incorrect to ignore the result of a method, it should raise an
exception, and not return a boolean ``True``/``False`` flag. For example, a
method to verify a signature should raise ``InvalidSignature``, and not return
@@ -287,5 +293,5 @@ The HTML documentation index can now be found at
.. _`tox`: https://pypi.python.org/pypi/tox
.. _`virtualenv`: https://pypi.python.org/pypi/virtualenv
.. _`pip`: https://pypi.python.org/pypi/pip
-.. _`sphinx`: https://pypi.python.org/pypi/sphinx
+.. _`sphinx`: https://pypi.python.org/pypi/Sphinx
.. _`reStructured Text`: http://sphinx-doc.org/rest.html
diff --git a/docs/exceptions.rst b/docs/exceptions.rst
index 1fbd3267..1e31e31c 100644
--- a/docs/exceptions.rst
+++ b/docs/exceptions.rst
@@ -10,8 +10,8 @@ Exceptions
.. class:: InvalidSignature
- This is raised when the verify method of a hash context does not
- compare equal.
+ This is raised when the verify method of a hash context's computed digest
+ does not match the expected digest.
.. class:: NotYetFinalized
@@ -30,3 +30,9 @@ Exceptions
This is raised when a backend doesn't support the requested algorithm (or
combination of algorithms).
+
+
+.. class:: InvalidKey
+
+ This is raised when the verify method of a key derivation function's
+ computed key does not match the expected key.
diff --git a/docs/fernet.rst b/docs/fernet.rst
index 13295c0c..b0215e32 100644
--- a/docs/fernet.rst
+++ b/docs/fernet.rst
@@ -72,5 +72,22 @@ symmetric (also known as "secret key") authenticated cryptography.
See :meth:`Fernet.decrypt` for more information.
+Implementation
+--------------
+
+Fernet is built on top of a number of standard cryptographic primitives.
+Specifically it uses:
+
+* :class:`~cryptography.hazmat.primitives.ciphers.algorithms.AES` in
+ :class:`~cryptography.hazmat.primitives.ciphers.modes.CBC` mode with a
+ 128-bit key for encryption; using
+ :class:`~cryptography.hazmat.primitives.ciphers.PKCS7` padding.
+* :class:`~cryptography.hazmat.primitives.hmac.HMAC` using
+ :class:`~cryptography.hazmat.primitives.hashes.SHA256` for authentication.
+* Initialization vectors are generated using ``os.urandom()``.
+
+For complete details consult the `specification`_.
+
.. _`Fernet`: https://github.com/fernet/spec/
+.. _`specification`: https://github.com/fernet/spec/blob/master/Spec.md
diff --git a/docs/hazmat/backends/interfaces.rst b/docs/hazmat/backends/interfaces.rst
index 11e2f2a2..49e4c88c 100644
--- a/docs/hazmat/backends/interfaces.rst
+++ b/docs/hazmat/backends/interfaces.rst
@@ -37,7 +37,7 @@ A specific ``backend`` may provide one or more of these interfaces.
.. method:: create_symmetric_encryption_ctx(cipher, mode)
Create a
- :class:`~cryptogrpahy.hazmat.primitives.interfaces.CipherContext` that
+ :class:`~cryptography.hazmat.primitives.interfaces.CipherContext` that
can be used for encrypting data with the symmetric ``cipher`` using
the given ``mode``.
@@ -56,7 +56,7 @@ A specific ``backend`` may provide one or more of these interfaces.
.. method:: create_symmetric_decryption_ctx(cipher, mode)
Create a
- :class:`~cryptogrpahy.hazmat.primitives.interfaces.CipherContext` that
+ :class:`~cryptography.hazmat.primitives.interfaces.CipherContext` that
can be used for decrypting data with the symmetric ``cipher`` using
the given ``mode``.
@@ -91,7 +91,7 @@ A specific ``backend`` may provide one or more of these interfaces.
.. method:: create_hash_ctx(algorithm)
Create a
- :class:`~cryptogrpahy.hazmat.primitives.interfaces.HashContext` that
+ :class:`~cryptography.hazmat.primitives.interfaces.HashContext` that
uses the specified ``algorithm`` to calculate a message digest.
:param algorithm: An instance of a
@@ -121,7 +121,7 @@ A specific ``backend`` may provide one or more of these interfaces.
.. method:: create_hmac_ctx(algorithm)
Create a
- :class:`~cryptogrpahy.hazmat.primitives.interfaces.HashContext` that
+ :class:`~cryptography.hazmat.primitives.interfaces.HashContext` that
uses the specified ``algorithm`` to calculate a hash-based message
authentication code.
@@ -131,3 +131,44 @@ A specific ``backend`` may provide one or more of these interfaces.
:returns:
:class:`~cryptography.hazmat.primitives.interfaces.HashContext`
+
+
+.. class:: PBKDF2HMACBackend
+
+ .. versionadded:: 0.2
+
+ A backend with methods for using PBKDF2 using HMAC as a PRF.
+
+ .. method:: pbkdf2_hmac_supported(algorithm)
+
+ Check if the specified ``algorithm`` is supported by this backend.
+
+ :param algorithm: An instance of a
+ :class:`~cryptography.hazmat.primitives.interfaces.HashAlgorithm`
+ provider.
+
+ :returns: ``True`` if the specified ``algorithm`` is supported for
+ PBKDF2 HMAC by this backend, otherwise ``False``.
+
+ .. method:: derive_pbkdf2_hmac(self, algorithm, length, salt, iterations,
+ key_material)
+
+ :param algorithm: An instance of a
+ :class:`~cryptography.hazmat.primitives.interfaces.HashAlgorithm`
+ provider.
+
+ :param int length: The desired length of the derived key. Maximum is
+ (2\ :sup:`32` - 1) * ``algorithm.digest_size``
+
+ :param bytes salt: A salt.
+
+ :param int iterations: The number of iterations to perform of the hash
+ function. This can be used to control the length of time the
+ operation takes. Higher numbers help mitigate brute force attacks
+ against derived keys.
+
+ :param bytes key_material: The key material to use as a basis for
+ the derived key. This is typically a password.
+
+ :return bytes: Derived key.
+
diff --git a/docs/hazmat/backends/openssl.rst b/docs/hazmat/backends/openssl.rst
index 469823f1..5ad00d03 100644
--- a/docs/hazmat/backends/openssl.rst
+++ b/docs/hazmat/backends/openssl.rst
@@ -39,32 +39,4 @@ CryptGenRandom on Windows). This engine is **active** by default when importing
the OpenSSL backend. It is added to the engine list but not activated if you
only import the binding.
-
-Using your own OpenSSL on Linux
--------------------------------
-
-Python links to OpenSSL for its own purposes and this can sometimes cause
-problems when you wish to use a different version of OpenSSL with cryptography.
-If you want to use cryptography with your own build of OpenSSL you will need to
-make sure that the build is configured correctly so that your version of
-OpenSSL doesn't conflict with Python's.
-
-The options you need to add allow the linker to identify every symbol correctly
-even when multiple versions of the library are linked into the same program. If
-you are using your distribution's source packages these will probably be
-patched in for you already, otherwise you'll need to use options something like
-this when configuring OpenSSL::
-
- ./config -Wl,--version-script=openssl.ld -Wl,-Bsymbolic-functions -fPIC shared
-
-You'll also need to generate your own ``openssl.ld`` file. For example::
-
- OPENSSL_1.0.1F_CUSTOM {
- global:
- *;
- };
-
-You should replace the version string on the first line as appropriate for your
-build.
-
.. _`OpenSSL`: https://www.openssl.org/
diff --git a/docs/hazmat/bindings/openssl.rst b/docs/hazmat/bindings/openssl.rst
index 373fe472..557f8c4d 100644
--- a/docs/hazmat/bindings/openssl.rst
+++ b/docs/hazmat/bindings/openssl.rst
@@ -22,6 +22,26 @@ These are `CFFI`_ bindings to the `OpenSSL`_ C library.
This is a ``cffi`` library. It can be used to call OpenSSL functions,
and access constants.
+ .. classmethod:: init_static_locks
+
+ Enables the best available locking callback for OpenSSL.
+ See :ref:`openssl-threading`.
+
+.. _openssl-threading:
+
+Threading
+---------
+
+``cryptography`` enables OpenSSLs `thread safety facilities`_ in two different
+ways depending on the configuration of your system. Normally the locking
+callbacks provided by your Python implementation specifically for OpenSSL will
+be used. However if you have linked ``cryptography`` to a different version of
+OpenSSL than that used by your Python implementation we enable an alternative
+locking callback. This version is implemented in Python and so may result in
+lower performance in some situations. In particular parallelism is reduced
+because it has to acquire the GIL whenever any lock operations occur within
+OpenSSL.
.. _`CFFI`: https://cffi.readthedocs.org/
.. _`OpenSSL`: https://www.openssl.org/
+.. _`thread safety facilities`: http://www.openssl.org/docs/crypto/threads.html
diff --git a/docs/hazmat/primitives/index.rst b/docs/hazmat/primitives/index.rst
index b115fdbc..bde07392 100644
--- a/docs/hazmat/primitives/index.rst
+++ b/docs/hazmat/primitives/index.rst
@@ -10,5 +10,6 @@ Primitives
hmac
symmetric-encryption
padding
+ key-derivation-functions
constant-time
interfaces
diff --git a/docs/hazmat/primitives/interfaces.rst b/docs/hazmat/primitives/interfaces.rst
index edb24cd9..09a5a4ce 100644
--- a/docs/hazmat/primitives/interfaces.rst
+++ b/docs/hazmat/primitives/interfaces.rst
@@ -102,3 +102,175 @@ Interfaces used by the symmetric cipher modes described in
Exact requirements of the nonce are described by the documentation of
individual modes.
+
+Asymmetric Interfaces
+~~~~~~~~~~~~~~~~~~~~~
+
+.. class:: RSAPrivateKey
+
+ .. versionadded:: 0.2
+
+ An `RSA`_ private key.
+
+ .. method:: public_key()
+
+ :return: :class:`~cryptography.hazmat.primitives.interfaces.RSAPublicKey`
+
+ An RSA public key object corresponding to the values of the private key.
+
+ .. attribute:: modulus
+
+ :type: int
+
+ The public modulus.
+
+ .. attribute:: public_exponent
+
+ :type: int
+
+ The public exponent.
+
+ .. attribute:: key_length
+
+ :type: int
+
+ The bit length of the modulus.
+
+ .. attribute:: p
+
+ :type: int
+
+ ``p``, one of the two primes composing the :attr:`modulus`.
+
+ .. attribute:: q
+
+ :type: int
+
+ ``q``, one of the two primes composing the :attr:`modulus`.
+
+ .. attribute:: d
+
+ :type: int
+
+ The private exponent.
+
+ .. attribute:: n
+
+ :type: int
+
+ The public modulus. Alias for :attr:`modulus`.
+
+ .. attribute:: e
+
+ :type: int
+
+ The public exponent. Alias for :attr:`public_exponent`.
+
+
+.. class:: RSAPublicKey
+
+ .. versionadded:: 0.2
+
+ An `RSA`_ public key.
+
+ .. attribute:: modulus
+
+ :type: int
+
+ The public modulus.
+
+ .. attribute:: key_length
+
+ :type: int
+
+ The bit length of the modulus.
+
+ .. attribute:: public_exponent
+
+ :type: int
+
+ The public exponent.
+
+ .. attribute:: n
+
+ :type: int
+
+ The public modulus. Alias for :attr:`modulus`.
+
+ .. attribute:: e
+
+ :type: int
+
+ The public exponent. Alias for :attr:`public_exponent`.
+
+
+Hash Algorithms
+~~~~~~~~~~~~~~~
+
+.. class:: HashAlgorithm
+
+ .. attribute:: name
+
+ :type: str
+
+ The standard name for the hash algorithm, for example: ``"sha256"`` or
+ ``"whirlpool"``.
+
+ .. attribute:: digest_size
+
+ :type: int
+
+ The size of the resulting digest in bytes.
+
+ .. attribute:: block_size
+
+ :type: int
+
+ The internal block size of the hash algorithm in bytes.
+
+
+Key Derivation Functions
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. class:: KeyDerivationFunction
+
+ .. versionadded:: 0.2
+
+ .. method:: derive(key_material)
+
+ :param key_material bytes: The input key material. Depending on what
+ key derivation function you are using this
+ could be either random material, or a user
+ supplied password.
+ :return: The new key.
+ :raises cryptography.exceptions.AlreadyFinalized: This is raised when
+ :meth:`derive` or
+ :meth:`verify` is
+ called more than
+ once.
+
+ This generates and returns a new key from the supplied key material.
+
+ .. method:: verify(key_material, expected_key)
+
+ :param key_material bytes: The input key material. This is the same as
+ ``key_material`` in :meth:`derive`.
+ :param expected_key bytes: The expected result of deriving a new key,
+ this is the same as the return value of
+ :meth:`derive`.
+ :raises cryptography.exceptions.InvalidKey: This is raised when the
+ derived key does not match
+ the expected key.
+ :raises cryptography.exceptions.AlreadyFinalized: This is raised when
+ :meth:`derive` or
+ :meth:`verify` is
+ called more than
+ once.
+
+ This checks whether deriving a new key from the supplied
+ ``key_material`` generates the same key as the ``expected_key``, and
+ raises an exception if they do not match. This can be used for
+ something like checking whether a user's password attempt matches the
+ stored derived key.
+
+.. _`RSA`: http://en.wikipedia.org/wiki/RSA_(cryptosystem)
diff --git a/docs/hazmat/primitives/key-derivation-functions.rst b/docs/hazmat/primitives/key-derivation-functions.rst
new file mode 100644
index 00000000..551dbd6d
--- /dev/null
+++ b/docs/hazmat/primitives/key-derivation-functions.rst
@@ -0,0 +1,125 @@
+.. hazmat::
+
+Key Derivation Functions
+========================
+
+.. currentmodule:: cryptography.hazmat.primitives.kdf
+
+Key derivation functions derive bytes suitable for cryptographic operations
+from passwords or other data sources using a pseudo-random function (PRF).
+Different KDFs are suitable for different tasks such as:
+
+* Cryptographic key derivation
+
+ Deriving a key suitable for use as input to an encryption algorithm.
+ Typically this means taking a password and running it through an algorithm
+ such as :class:`~cryptography.hazmat.primitives.kdf.pbkdf2.PBKDF2HMAC` or HKDF.
+ This process is typically known as `key stretching`_.
+
+* Password storage
+
+ When storing passwords you want to use an algorithm that is computationally
+ intensive. Legitimate users will only need to compute it once (for example,
+ taking the user's password, running it through the KDF, then comparing it
+ to the stored value), while attackers will need to do it billions of times.
+ Ideal password storage KDFs will be demanding on both computational and
+ memory resources.
+
+.. currentmodule:: cryptography.hazmat.primitives.kdf.pbkdf2
+
+.. class:: PBKDF2HMAC(algorithm, length, salt, iterations, backend)
+
+ .. versionadded:: 0.2
+
+ `PBKDF2`_ (Password Based Key Derivation Function 2) is typically used for
+ deriving a cryptographic key from a password. It may also be used for
+ key storage, but an alternate key storage KDF such as `scrypt`_ is generally
+ considered a better solution.
+
+ This class conforms to the
+ :class:`~cryptography.hazmat.primitives.interfaces.KeyDerivationFunction`
+ interface.
+
+ .. doctest::
+
+ >>> import os
+ >>> from cryptography.hazmat.primitives import hashes
+ >>> from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
+ >>> from cryptography.hazmat.backends import default_backend
+ >>> backend = default_backend()
+ >>> salt = os.urandom(16)
+ >>> # derive
+ >>> kdf = PBKDF2HMAC(
+ ... algorithm=hashes.SHA256(),
+ ... length=32,
+ ... salt=salt,
+ ... iterations=100000,
+ ... backend=backend
+ ... )
+ >>> key = kdf.derive(b"my great password")
+ >>> # verify
+ >>> kdf = PBKDF2HMAC(
+ ... algorithm=hashes.SHA256(),
+ ... length=32,
+ ... salt=salt,
+ ... iterations=100000,
+ ... backend=backend
+ ... )
+ >>> kdf.verify(b"my great password", key)
+
+ :param algorithm: An instance of a
+ :class:`~cryptography.hazmat.primitives.interfaces.HashAlgorithm`
+ provider.
+ :param int length: The desired length of the derived key. Maximum is
+ (2\ :sup:`32` - 1) * ``algorithm.digest_size``.
+ :param bytes salt: A salt. `NIST SP 800-132`_ recommends 128-bits or
+ longer.
+ :param int iterations: The number of iterations to perform of the hash
+ function. This can be used to control the length of time the operation
+ takes. Higher numbers help mitigate brute force attacks against derived
+ keys. See OWASP's `Password Storage Cheat Sheet`_ for more
+ detailed recommendations if you intend to use this for password storage.
+ :param backend: A
+ :class:`~cryptography.hazmat.backends.interfaces.PBKDF2HMACBackend`
+ provider.
+
+ .. method:: derive(key_material)
+
+ :param key_material bytes: The input key material. For PBKDF2 this
+ should be a password.
+ :return bytes: the derived key.
+ :raises cryptography.exceptions.AlreadyFinalized: This is raised when
+ :meth:`derive` or
+ :meth:`verify` is
+ called more than
+ once.
+
+ This generates and returns a new key from the supplied password.
+
+ .. method:: verify(key_material, expected_key)
+
+ :param key_material bytes: The input key material. This is the same as
+ ``key_material`` in :meth:`derive`.
+ :param expected_key bytes: The expected result of deriving a new key,
+ this is the same as the return value of
+ :meth:`derive`.
+ :raises cryptography.exceptions.InvalidKey: This is raised when the
+ derived key does not match
+ the expected key.
+ :raises cryptography.exceptions.AlreadyFinalized: This is raised when
+ :meth:`derive` or
+ :meth:`verify` is
+ called more than
+ once.
+
+ This checks whether deriving a new key from the supplied
+ ``key_material`` generates the same key as the ``expected_key``, and
+ raises an exception if they do not match. This can be used for
+ checking whether the password a user provides matches the stored derived
+ key.
+
+.. _`NIST SP 800-132`: http://csrc.nist.gov/publications/nistpubs/800-132/nist-sp800-132.pdf
+.. _`Password Storage Cheat Sheet`: https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet
+.. _`PBKDF2`: http://en.wikipedia.org/wiki/PBKDF2
+.. _`scrypt`: http://en.wikipedia.org/wiki/Scrypt
+.. _`key stretching`: http://en.wikipedia.org/wiki/Key_stretching
diff --git a/docs/index.rst b/docs/index.rst
index e17b4f9f..86cd42c6 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -5,15 +5,16 @@ Welcome to ``cryptography``
primitives. We hope it'll be your one-stop-shop for all your cryptographic
needs in Python.
-Installing
-----------
-
+Installation
+------------
You can install ``cryptography`` with ``pip``:
.. code-block:: console
$ pip install cryptography
+See :doc:`Installation <installation>` for more information.
+
Why a new crypto library for Python?
------------------------------------
@@ -75,9 +76,13 @@ The ``cryptography`` open source project
.. toctree::
:maxdepth: 2
+ installation
contributing
security
api-stability
doing-a-release
changelog
community
+
+
+.. _`pre-compiled binaries`: https://www.openssl.org/related/binaries.html
diff --git a/docs/installation.rst b/docs/installation.rst
new file mode 100644
index 00000000..2206107e
--- /dev/null
+++ b/docs/installation.rst
@@ -0,0 +1,74 @@
+Installing
+==========
+
+You can install ``cryptography`` with ``pip``:
+
+.. code-block:: console
+
+ $ pip install cryptography
+
+Installation Notes
+==================
+On Windows
+----------
+If you're on Windows you'll need to make sure you have OpenSSL installed.
+There are `pre-compiled binaries`_ available. If your installation is in
+an unusual location set the ``LIB`` and ``INCLUDE`` environment variables
+to include the corresponding locations. For example:
+
+.. code-block:: console
+
+ C:\> \path\to\vcvarsall.bat x86_amd64
+ C:\> set LIB=C:\OpenSSL-1.0.1f-64bit\lib;%LIB%
+ C:\> set INCLUDE=C:\OpenSSL-1.0.1f-64bit\include;%INCLUDE%
+ C:\> pip install cryptography
+
+Using your own OpenSSL on Linux
+-------------------------------
+
+Python links to OpenSSL for its own purposes and this can sometimes cause
+problems when you wish to use a different version of OpenSSL with cryptography.
+If you want to use cryptography with your own build of OpenSSL you will need to
+make sure that the build is configured correctly so that your version of
+OpenSSL doesn't conflict with Python's.
+
+The options you need to add allow the linker to identify every symbol correctly
+even when multiple versions of the library are linked into the same program. If
+you are using your distribution's source packages these will probably be
+patched in for you already, otherwise you'll need to use options something like
+this when configuring OpenSSL:
+
+.. code-block:: console
+
+ $ ./config -Wl,--version-script=openssl.ld -Wl,-Bsymbolic-functions -fPIC shared
+
+You'll also need to generate your own ``openssl.ld`` file. For example::
+
+ OPENSSL_1.0.1F_CUSTOM {
+ global:
+ *;
+ };
+
+You should replace the version string on the first line as appropriate for your
+build.
+
+Using your own OpenSSL on OS X
+------------------------------
+
+To link cryptography against a custom version of OpenSSL you'll need to set
+``ARCHFLAGS``, ``LDFLAGS``, and ``CFLAGS``. OpenSSL can be installed via
+`Homebrew`_:
+
+.. code-block:: console
+
+ $ brew install openssl
+
+Then install cryptography linking against the brewed version:
+
+.. code-block:: console
+
+ $ env ARCHFLAGS="-arch x86_64" LDFLAGS="-L/usr/local/opt/openssl/lib" CFLAGS="-I/usr/local/opt/openssl/include" pip install cryptography
+
+
+.. _`Homebrew`: http://brew.sh
+.. _`pre-compiled binaries`: https://www.openssl.org/related/binaries.html