1Classic modes of operation for symmetric block ciphers 2====================================================== 3 4A block cipher uses a symmetric key to encrypt data of fixed and very short length 5(the *block size*), such as 16 bytes for AES. 6In order to cope with data of arbitrary length, the cipher must be 7combined with a *mode of operation*. 8 9You create a cipher object with the :func:`new` function 10in the relevant module under ``Crypto.Cipher``: 11 121. the first parameter is always the cryptographic key (a byte string) 132. the second parameter is always the constant that selects the desired 14 mode of operation 15 16Constants for each mode of operation are defined at the module level for each algorithm. 17Their name starts with ``MODE_``, for instance :const:`Crypto.Cipher.AES.MODE_CBC`. 18Note that not all ciphers support all modes. 19 20For instance:: 21 22 >>> from Crypto.Cipher import AES 23 >>> from Crypto.Random import get_random_bytes 24 >>> 25 >>> key = get_random_bytes(16) 26 >>> cipher = AES.new(key, AES.MODE_CBC) 27 >>> 28 >>> # You can now use use cipher to encrypt or decrypt... 29 30The state machine for a cipher configured with a classic mode is: 31 32.. figure:: simple_mode.png 33 :align: center 34 :figwidth: 50% 35 36 Generic state diagram for a cipher object 37 38What follows is a list of classic modes of operation: they all provide confidentiality 39but not data integrity (unlike modern AEAD modes, which are described in :doc:`another section <modern>`). 40 41.. _ecb_mode: 42 43ECB mode 44-------- 45`Electronic CodeBook <https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_Codebook_.28ECB.29>`_. 46The most basic but also the weakest mode of operation. 47Each block of plaintext is encrypted independently of any other block. 48 49.. warning:: 50 The ECB mode should not be used because it is `semantically insecure <https://en.wikipedia.org/wiki/Semantic_security>`_. 51 For one, it exposes correlation between blocks. 52 53The :func:`new` function at the module level under ``Crypto.Cipher`` instantiates 54a new ECB cipher object for the relevant base algorithm. 55In the following definition, ``<algorithm>`` could be ``AES``: 56 57.. function:: Crypto.Cipher.<algorithm>.new(key, mode) 58 59 Create a new ECB object, using <algorithm> as the base block cipher. 60 61 :param bytes key: the cryptographic key 62 :param mode: the constant ``Crypto.Cipher.<algorithm>.MODE_ECB`` 63 :return: an ECB cipher object 64 65The method :func:`encrypt` (and likewise :func:`decrypt`) of an ECB cipher object 66expects data to have length multiple of the block size (e.g. 16 bytes for AES). 67You might need to use :mod:`Crypto.Util.Padding` to align the plaintext to the right boundary. 68 69.. _cbc_mode: 70 71CBC mode 72-------- 73`Ciphertext Block Chaining <https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_Block_Chaining_.28CBC.29>`_, 74defined in `NIST SP 800-38A, section 6.2 <http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf>`_. 75It is a mode of operation where each plaintext block 76gets XOR-ed with the previous ciphertext block prior to encryption. 77 78The :func:`new` function at the module level under ``Crypto.Cipher`` instantiates 79a new CBC cipher object for the relevant base algorithm. 80In the following definition, ``<algorithm>`` could be ``AES``: 81 82.. function:: Crypto.Cipher.<algorithm>.new(key, mode, *, iv=None) 83 84 Create a new CBC object, using <algorithm> as the base block cipher. 85 86 :param bytes key: the cryptographic key 87 :param mode: the constant ``Crypto.Cipher.<algorithm>.MODE_CBC`` 88 :param bytes iv: the *Initialization Vector*. A piece of data unpredictable to adversaries. 89 It is as long as the block size (e.g. 16 bytes for AES). 90 If not present, the library creates a random IV value. 91 :return: a CBC cipher object 92 93The method :func:`encrypt` (and likewise :func:`decrypt`) of a CBC cipher object 94expects data to have length multiple of the block size (e.g. 16 bytes for AES). 95You might need to use :mod:`Crypto.Util.Padding` to align the plaintext to the right boundary. 96 97A CBC cipher object has a read-only attribute :attr:`iv`, holding the 98*Initialization Vector* (*bytes*). 99 100Example (encryption):: 101 102 >>> import json 103 >>> from base64 import b64encode 104 >>> from Crypto.Cipher import AES 105 >>> from Crypto.Util.Padding import pad 106 >>> from Crypto.Random import get_random_bytes 107 >>> 108 >>> data = b"secret" 109 >>> key = get_random_bytes(16) 110 >>> cipher = AES.new(key, AES.MODE_CBC) 111 >>> ct_bytes = cipher.encrypt(pad(data, AES.block_size)) 112 >>> iv = b64encode(cipher.iv).decode('utf-8') 113 >>> ct = b64encode(ct_bytes).decode('utf-8') 114 >>> result = json.dumps({'iv':iv, 'ciphertext':ct}) 115 >>> print(result) 116 '{"iv": "bWRHdzkzVDFJbWNBY0EwSmQ1UXFuQT09", "ciphertext": "VDdxQVo3TFFCbXIzcGpYa1lJbFFZQT09"}' 117 118Example (decryption):: 119 120 >>> import json 121 >>> from base64 import b64decode 122 >>> from Crypto.Cipher import AES 123 >>> from Crypto.Util.Padding import unpad 124 >>> 125 >>> # We assume that the key was securely shared beforehand 126 >>> try: 127 >>> b64 = json.loads(json_input) 128 >>> iv = b64decode(b64['iv']) 129 >>> ct = b64decode(b64['ciphertext']) 130 >>> cipher = AES.new(key, AES.MODE_CBC, iv) 131 >>> pt = unpad(cipher.decrypt(ct), AES.block_size) 132 >>> print("The message was: ", pt) 133 >>> except ValueError, KeyError: 134 >>> print("Incorrect decryption") 135 136.. _ctr_mode: 137 138CTR mode 139-------- 140`CounTeR mode <https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_.28CTR.29>`_, 141defined in `NIST SP 800-38A, section 6.5 and Appendix B <http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf>`_. 142This mode turns the block cipher into a stream cipher. 143Each byte of plaintext is XOR-ed with a byte taken from a *keystream*: the result is the ciphertext. 144The *keystream* is generated by encrypting a sequence of *counter blocks* with ECB. 145 146.. figure:: ctr_mode.png 147 :align: center 148 149A *counter block* is exactly as long as the cipher block size (e.g. 16 bytes for AES). 150It consist of the concatenation of two pieces: 151 1521. a fixed **nonce**, set at initialization. 1532. a variable **counter**, which gets increased by 1 for any subsequent counter block. 154 The counter is big endian encoded. 155 156The :func:`new` function at the module level under ``Crypto.Cipher`` instantiates 157a new CTR cipher object for the relevant base algorithm. 158In the following definition, ``<algorithm>`` could be ``AES``: 159 160.. function:: Crypto.Cipher.<algorithm>.new(key, mode, *, nonce=None, initial_value=None, counter=None) 161 162 Create a new CTR object, using <algorithm> as the base block cipher. 163 164 :param bytes key: the cryptographic key 165 :param mode: the constant ``Crypto.Cipher.<algorithm>.MODE_CTR`` 166 :param bytes nonce: the value of the fixed nonce. 167 It must be unique for the combination message/key. 168 Its length varies from 0 to the block size minus 1. 169 If not present, the library creates a random nonce of length equal to block size/2. 170 :param initial_value: the value of the counter for the first counter block. 171 It can be either an integer or *bytes* (which is the same integer, just big endian encoded). 172 If not specified, the counter starts at 0. 173 :type initial_value: integer or bytes 174 :param counter: a custom counter object created with :func:`Crypto.Util.Counter.new`. 175 This allows the definition of a more complex counter block. 176 :return: a CTR cipher object 177 178The methods :func:`encrypt` and :func:`decrypt` of a CTR cipher object 179accept data of any length (i.e. padding is not needed). 180Both raise an ``OverflowError`` exception as soon as the counter wraps around to repeat the original value. 181 182The CTR cipher object has a read-only attribute :attr:`nonce` (*bytes*). 183 184Example (encryption):: 185 186 >>> import json 187 >>> from base64 import b64encode 188 >>> from Crypto.Cipher import AES 189 >>> from Crypto.Random import get_random_bytes 190 >>> 191 >>> data = b"secret" 192 >>> key = get_random_bytes(16) 193 >>> cipher = AES.new(key, AES.MODE_CTR) 194 >>> ct_bytes = cipher.encrypt(data) 195 >>> nonce = b64encode(cipher.nonce).decode('utf-8') 196 >>> ct = b64encode(ct_bytes).decode('utf-8') 197 >>> result = json.dumps({'nonce':nonce, 'ciphertext':ct}) 198 >>> print(result) 199 {"nonce": "XqP8WbylRt0=", "ciphertext": "Mie5lqje"} 200 201Example (decryption):: 202 203 >>> import json 204 >>> from base64 import b64decode 205 >>> from Crypto.Cipher import AES 206 >>> 207 >>> # We assume that the key was securely shared beforehand 208 >>> try: 209 >>> b64 = json.loads(json_input) 210 >>> nonce = b64decode(b64['nonce']) 211 >>> ct = b64decode(b64['ciphertext']) 212 >>> cipher = AES.new(key, AES.MODE_CTR, nonce=nonce) 213 >>> pt = cipher.decrypt(ct) 214 >>> print("The message was: ", pt) 215 >>> except ValueError, KeyError: 216 >>> print("Incorrect decryption") 217 218.. _cfb_mode: 219 220CFB mode 221-------- 222`Cipher FeedBack <https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_Codebook_.28ECB.29>`_, 223defined in `NIST SP 800-38A, section 6.3 <http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf>`_. 224It is a mode of operation which turns the block cipher into a stream cipher. 225Each byte of plaintext is XOR-ed with a byte taken from a *keystream*: the result is the ciphertext. 226 227The *keystream* is obtained on a per-segment basis: the plaintext is broken up in 228segments (from 1 byte up to the size of a block). Then, for each segment, 229the keystream is obtained by encrypting with the block cipher the last piece of 230ciphertext produced so far - possibly backfilled with the *Initialization Vector*, 231if not enough ciphertext is available yet. 232 233The :func:`new` function at the module level under ``Crypto.Cipher`` instantiates 234a new CFB cipher object for the relevant base algorithm. 235In the following definition, ``<algorithm>`` could be ``AES``: 236 237.. function:: Crypto.Cipher.<algorithm>.new(key, mode, *, iv=None, segment_size=8) 238 239 Create a new CFB object, using <algorithm> as the base block cipher. 240 241 :param bytes key: the cryptographic key 242 :param mode: the constant ``Crypto.Cipher.<algorithm>.MODE_CFB`` 243 :param bytes iv: the *Initialization Vector*. 244 It must be unique for the combination message/key. 245 It is as long as the block size (e.g. 16 bytes for AES). 246 If not present, the library creates a random IV. 247 :param integer segment_size: the number of **bits** (not bytes!) the plaintext and the 248 ciphertext are segmented in (default if not specified: 8 bits = 1 byte). 249 :return: a CFB cipher object 250 251The methods :func:`encrypt` and :func:`decrypt` of a CFB cipher object 252accept data of any length (i.e. padding is not needed). 253 254The CFB cipher object has a read-only attribute :attr:`iv` (*bytes*), holding 255the Initialization Vector. 256 257Example (encryption):: 258 259 >>> import json 260 >>> from base64 import b64encode 261 >>> from Crypto.Cipher import AES 262 >>> from Crypto.Random import get_random_bytes 263 >>> 264 >>> data = b"secret" 265 >>> key = get_random_bytes(16) 266 >>> cipher = AES.new(key, AES.MODE_CFB) 267 >>> ct_bytes = cipher.encrypt(data) 268 >>> iv = b64encode(cipher.iv).decode('utf-8') 269 >>> ct = b64encode(ct_bytes).decode('utf-8') 270 >>> result = json.dumps({'iv':iv, 'ciphertext':ct}) 271 >>> print(result) 272 {"iv": "VoamO23kFSOZcK1O2WiCDQ==", "ciphertext": "f8jciJ8/"} 273 274Example (decryption):: 275 276 >>> import json 277 >>> from base64 import b64decode 278 >>> from Crypto.Cipher import AES 279 >>> 280 >>> # We assume that the key was securely shared beforehand 281 >>> try: 282 >>> b64 = json.loads(json_input) 283 >>> iv = b64decode(b64['iv']) 284 >>> ct = b64decode(b64['ciphertext']) 285 >>> cipher = AES.new(key, AES.MODE_CFB, iv=iv) 286 >>> pt = cipher.decrypt(ct) 287 >>> print("The message was: ", pt) 288 >>> except ValueError, KeyError: 289 >>> print("Incorrect decryption") 290 291.. _ofb_mode: 292 293OFB mode 294-------- 295`Output FeedBack <https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Output_Feedback_.28OFB.29>`_, 296defined in `NIST SP 800-38A, section 6.4 <http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf>`_. 297It is another mode that leads to a stream cipher. 298Each byte of plaintext is XOR-ed with a byte taken from a *keystream*: the result is the ciphertext. 299The *keystream* is obtained by recursively encrypting the *Initialization Vector*. 300 301The :func:`new` function at the module level under ``Crypto.Cipher`` instantiates 302a new OFB cipher object for the relevant base algorithm. 303In the following definition, ``<algorithm>`` could be ``AES``: 304 305.. function:: Crypto.Cipher.<algorithm>.new(key, mode, *, iv=None) 306 307 Create a new OFB object, using <algorithm> as the base block cipher. 308 309 :param bytes key: the cryptographic key 310 :param mode: the constant ``Crypto.Cipher.<algorithm>.MODE_OFB`` 311 :param bytes iv: the *Initialization Vector*. 312 It must be unique for the combination message/key. 313 It is as long as the block size (e.g. 16 bytes for AES). 314 If not present, the library creates a random IV. 315 :return: an OFB cipher object 316 317The methods :func:`encrypt` and :func:`decrypt` of an OFB cipher object 318accept data of any length (i.e. padding is not needed). 319 320The OFB cipher object has a read-only attribute :attr:`iv` (*bytes*), holding 321the Initialization Vector. 322 323Example (encryption):: 324 325 >>> import json 326 >>> from base64 import b64encode 327 >>> from Crypto.Cipher import AES 328 >>> from Crypto.Random import get_random_bytes 329 >>> 330 >>> data = b"secret" 331 >>> key = get_random_bytes(16) 332 >>> cipher = AES.new(key, AES.MODE_OFB) 333 >>> ct_bytes = cipher.encrypt(data) 334 >>> iv = b64encode(cipher.iv).decode('utf-8') 335 >>> ct = b64encode(ct_bytes).decode('utf-8') 336 >>> result = json.dumps({'iv':iv, 'ciphertext':ct}) 337 >>> print(result) 338 {"iv": "NUuRJbL0UMp8+UMCk2/vQA==", "ciphertext": "XGVGc1Gw"} 339 340Example (decryption):: 341 342 >>> import json 343 >>> from base64 import b64decode 344 >>> from Crypto.Cipher import AES 345 >>> 346 >>> # We assume that the key was securely shared beforehand 347 >>> try: 348 >>> b64 = json.loads(json_input) 349 >>> iv = b64decode(b64['iv']) 350 >>> ct = b64decode(b64['ciphertext']) 351 >>> cipher = AES.new(key, AES.MODE_OFB, iv=iv) 352 >>> pt = cipher.decrypt(ct) 353 >>> print("The message was: ", pt) 354 >>> except ValueError, KeyError: 355 >>> print("Incorrect decryption") 356 357.. _openpgp_mode: 358 359OpenPGP mode 360------------ 361Constant: ``Crypto.Cipher.<cipher>.MODE_OPENPGP``. 362 363OpenPGP (defined in `RFC4880 <https://tools.ietf.org/html/rfc4880>`_). 364A variant of CFB, with two differences: 365 3661. The first invocation to the :func:`encrypt` method 367 returns the encrypted IV concatenated to the first chunk 368 of ciphertext (as opposed to the ciphertext only). 369 The encrypted IV is as long as the block size plus 2 more bytes. 370 3712. When the cipher object is intended for decryption, 372 the parameter ``iv`` to :func:`new` is the encrypted IV 373 (and not the IV, which is still the case for encryption). 374 375Like for CTR, an OpenPGP cipher object has a read-only attribute :attr:`iv`. 376 377