Crypto.Cipher package

Introduction

The Crypto.Cipher package contains algorithms for protecting the confidentiality of data.

There are three types of encryption algorithms:

  1. Symmetric ciphers: all parties use the same key, for both decrypting and encrypting data. Symmetric ciphers are typically very fast and can process very large amount of data.
  2. Asymmetric ciphers: senders and receivers use different keys. Senders encrypt with public keys (non-secret) whereas receivers decrypt with private keys (secret). Asymmetric ciphers are typically very slow and can process only very small payloads. Example: PKCS#1 OAEP (RSA).
  3. Hybrid ciphers: the two types of ciphers above can be combined in a construction that inherits the benefits of both. An asymmetric cipher is used to protect a short-lived symmetric key, and a symmetric cipher (under that key) encrypts the actual message.

API principles

../../_images/simple_mode.png

Generic state diagram for a cipher object

The base API of a cipher is fairly simple:

  • You instantiate a cipher object by calling the new() function from the relevant cipher module (e.g. Crypto.Cipher.AES.new()). The first parameter is always the cryptographic key; its length depends on the particular cipher. You can (and sometimes must) pass additional cipher- or mode-specific parameters to new() (such as a nonce or a mode of operation).
  • For encrypting, you call the encrypt() method of the cipher object with the plaintext. The method returns the piece of ciphertext. For most algorithms, you may call encrypt() multiple times (i.e. once for each piece of plaintext).
  • For decrypting, you call the decrypt() method of the cipher object with the ciphertext. The method returns the piece of plaintext. For most algorithms, you may call decrypt() multiple times (i.e. once for each piece of ciphertext).

Note

Plaintexts and ciphertexts (input/output) are all byte strings. An error will occur with Python 3 strings, Python 2 Unicode strings, or byte arrays.

Often, the sender has to deliver to the receiver other data in addition to ciphertext alone (e.g. initialization vectors or nonces, MAC tags, etc).

This is a basic example:

>>> from Crypto.Cipher import Salsa20
>>>
>>> key = b'0123456789012345'
>>> cipher = Salsa20.new(key)
>>> ciphertext =  cipher.encrypt(b'The secret I want to send.')
>>> ciphertext += cipher.encrypt(b'The second part of the secret.')
>>> print cipher.nonce  # A byte string you must send to the receiver too

Symmetric ciphers

There are two types of symmetric ciphers:

  • Stream ciphers: the most natural kind of ciphers; they encrypt any piece of data by preserving its length: see ChaCha20, Salsa20.

  • Block ciphers: ciphers that can only operate on a fixed amount of data. The most important block cipher is AES, which has a block size of 16 bytes.

    A block cipher is in general useful only in combination with a mode of operation . There are classic modes like CTR or authenticated modes like GCM.

Historic ciphers

A number of ciphers are implemented in this library purely for backward compatibility purposes. They are deprecated or even fully broken and should not be used in new designs.