Cobblestone (streaming symmetric encryption) ============================================= .. currentmodule:: cryptography.cobblestone Cobblestone provides authenticated symmetric encryption of large messages — up to 4 PiB — as a stream, without ever holding the whole message in memory. It is an implementation of the `C2SP chunked-encryption specification`_'s two named instantiations: **Cobblestone-128** (SHA-512 and AES-128-GCM, the recommended choice) and **Cobblestone-256** (SHA-512 and AES-256-GCM, for environments that mandate 256-bit keys). .. doctest:: >>> from cryptography.cobblestone import ( ... Cobblestone128Decryptor, Cobblestone128Encryptor ... ) >>> key = Cobblestone128Encryptor.generate_key() >>> encryptor = Cobblestone128Encryptor( ... key, context=b"example-app file encryption" ... ) >>> ciphertext = encryptor.update(b"a secret message") >>> ciphertext += encryptor.finalize() >>> decryptor = Cobblestone128Decryptor( ... key, context=b"example-app file encryption" ... ) >>> decryptor.update(ciphertext) + decryptor.finalize() b'a secret message' .. class:: Cobblestone128Encryptor(key, context) .. versionadded:: 50.0.0 Encrypts a single message under ``key`` with Cobblestone-128. Each instance must be used for exactly one message: call :meth:`update` (or :meth:`update_into`) any number of times, then call :meth:`finalize` exactly once. The concatenation of the returned bytes is the ciphertext. :param key: A 16-byte key. This **must** be kept secret, and **must** be uniformly random (e.g. the output of :meth:`generate_key` — never a password). A single key may be used to encrypt a practically unlimited number of messages. :type key: :term:`bytes-like` :param context: Application-provided context, bound to the ciphertext. Decryption fails unless the same value is passed to :class:`Cobblestone128Decryptor`. It is not secret, may be empty, and is not part of the ciphertext, so it must be available to the decrypting party independently. It can be used for domain separation, e.g. ``b"myapp v2 backup encryption"``. :type context: :term:`bytes-like` :raises ValueError: If ``key`` is not 16 bytes. .. staticmethod:: generate_key() Generates a fresh 16-byte key. :return bytes: A new key. .. method:: update(data) Encrypts ``data``. Data is internally buffered into 16 KiB chunks, so between 0 and ``len(data) + 16 KiB`` bytes of ciphertext are returned. :param data: The data to encrypt. :type data: :term:`bytes-like` :return bytes: The next portion of the ciphertext. .. method:: update_into(data, buf) Encrypts ``data``, writing the resulting ciphertext into ``buf``, and returns the number of bytes written. This avoids allocating a new buffer for each call. :param data: The data to encrypt. :type data: :term:`bytes-like` :param buf: A writable buffer to write the ciphertext into. A buffer of ``len(data) + len(data) // 1024 + 16456`` bytes is always large enough. :type buf: :term:`bytes-like` :return int: The number of bytes written to ``buf``. :raises ValueError: If ``buf`` is too small. .. method:: finalize() Encrypts the final chunk and returns the last portion of the ciphertext. This must always be called, and the instance cannot be used afterwards. :return bytes: The remainder of the ciphertext. :raises cryptography.exceptions.AlreadyFinalized: If ``finalize`` has already been called. .. class:: Cobblestone128Decryptor(key, context) .. versionadded:: 50.0.0 Decrypts a single message encrypted by :class:`Cobblestone128Encryptor` with the same ``key`` and ``context``. Call :meth:`update` (or :meth:`update_into`) with the ciphertext any number of times, then call :meth:`finalize` exactly once. The concatenation of the returned bytes is the plaintext. Any returned plaintext is authenticated, but until :meth:`finalize` returns successfully the message could still turn out to be truncated: an application acting on streamed plaintext before that point must be prepared to discard its work if a later call raises :class:`~cryptography.exceptions.InvalidTag`. Once any method raises :class:`~cryptography.exceptions.InvalidTag`, the instance is permanently unusable and all further calls raise :class:`~cryptography.exceptions.AlreadyFinalized`. :param key: The 16-byte key the message was encrypted with. :type key: :term:`bytes-like` :param context: The context value the message was encrypted with. :type context: :term:`bytes-like` :raises ValueError: If ``key`` is not 16 bytes. .. method:: update(data) Processes ``data``, which need not be aligned to any boundary, and returns the plaintext of all complete chunks that have been authenticated so far. :param data: The next portion of the ciphertext. :type data: :term:`bytes-like` :return bytes: The next portion of the plaintext. :raises cryptography.exceptions.InvalidTag: If the ciphertext was encrypted with a different key or context, or has been modified. .. method:: update_into(data, buf) Like ``update``, but writes the plaintext into ``buf`` and returns the number of bytes written. :param data: The next portion of the ciphertext. :type data: :term:`bytes-like` :param buf: A writable buffer to write the plaintext into. A buffer of ``len(data) + 16400`` bytes is always large enough. :type buf: :term:`bytes-like` :return int: The number of bytes written to ``buf``. :raises ValueError: If ``buf`` is too small. :raises cryptography.exceptions.InvalidTag: If the ciphertext was encrypted with a different key or context, or has been modified. Note that in this case unauthenticated data may have been written to ``buf`` and must not be used. .. method:: finalize() Decrypts and authenticates the final chunk, verifying that the entire message has been processed, and returns the final portion of the plaintext. This must always be called: a successful return is what guarantees the complete message was authentic and not truncated. :return bytes: The remainder of the plaintext. :raises cryptography.exceptions.InvalidTag: If the ciphertext was truncated or otherwise modified. :raises cryptography.exceptions.AlreadyFinalized: If ``finalize`` has already been called. .. class:: Cobblestone256Encryptor(key, context) .. versionadded:: 50.0.0 Exactly like :class:`Cobblestone128Encryptor`, but implements Cobblestone-256: the ``key`` is 32 bytes and messages are encrypted with AES-256-GCM. Use this when a 256-bit key is mandated; otherwise Cobblestone-128 is recommended. .. class:: Cobblestone256Decryptor(key, context) .. versionadded:: 50.0.0 Exactly like :class:`Cobblestone128Decryptor`, but decrypts messages produced by :class:`Cobblestone256Encryptor` with a 32-byte key. .. _`C2SP chunked-encryption specification`: https://c2sp.org/chunked-encryption