Library reference¶
This module creates PEP-272 cipher object classes for building block ciphers in python.
To use, inherit the PEP272Cipher and overwrite
encrypt_block
or decrypt_block(self, key, string, **kwargs)
methods
and set the block_size attribute.
Example:
class YourCipher(PEP272Cipher):
block_size=8
def encrypt_block(self, key, string, **kwargs):
...
def decrypt_block(self, key_string, **kwargs):
...
The PEP272Cipher class¶
Subclass and overwrite the PEP272Cipher.encrypt_block and PEP272Cipher.decrypt_block methods and the block_size attribute.
-
class
pep272_encryption.
PEP272Cipher
(key, mode, IV=None, **kwargs)¶ A cipher class as defined in PEP-272.
Parameters: - key (bytes) – The symmetric key to use for encryption.
- mode (int) – The mode of operation to use. For valid values see Reference/Block cipher mode of operation.
- IV (bytes) – A unique bytestring with once the block size in length. For security reasons it should be unpredictable and must never be used twice for the same key. Required for CBC, CFB and OFB mode of operation.
- **kwargs – See below.
Depending on the blockcipher mode of operation one or multiple of the following arguments must be passed depending on the mode of operation.
Keyword arguments: - iv (bytes) – Alternative name for IV
- segment_size (int): The segment size for one encryption “segment” of CFB mode in bits. It must be multiple of 8 (only byte-sized operations are allowed) and the maximum size is the block size * 8. Required for CFB mode of operation.
- counter (callable):
A callable object returning block size bytes or a counter
from
Crypto.Util.Counter
. For security reasons the counter output must never repeat. Required for CTR mode. - Additional keyword arguments are passed to the underlying block cipher implementation as kwargs.
Changed in version 0.4: IV can be used as a positional argument.
Changed in version 0.4: PyCryptodome counters are accepted for counter in addition to to callables.
-
decrypt
(string)¶ Decrypt data with the key and the parameters set at initialization.
The cipher object is stateful; decryption of a long block of data can be broken up in two or more calls to decrypt(). That is, the statement:
>>> c.decrypt(a) + c.decrypt(b)
is always equivalent to:
>>> c.decrypt(a+b)
That also means that you cannot reuse an object for encrypting or decrypting other data with the same key.
This function does not perform any padding.
- For MODE_ECB, MODE_CBC string length (in bytes) must be a multiple of block_size.
- For MODE_CFB, string length (in bytes) must be a multiple of segment_size/8.
- For MODE_CTR and MODE_OFB, string can be of any length.
Parameters: string (bytes) – The piece of data to decrypt.
Raises: - ValueError – When a mode of operation has be requested this code cannot handle.
- ValueError – When len(string) has a wrong length, as described above.
- TypeError – When the counter in CTR returns data of the wrong length.
Returns: The decrypted data, as a byte string. It is as long as string.
Return type:
-
decrypt_block
(key, block, **kwargs)¶ Dummy function for the decryption of a single block. Overwrite with ‘real’ deryption function.
Parameters: Raises: NotImplementedError – This method is to be overridden.
Returns: plaintext block
Return type:
-
encrypt
(string)¶ Encrypt data with the key and the parameters set at initialization.
The cipher object is stateful; encryption of a long block of data can be broken up in two or more calls to encrypt(). That is, the statement:
>>> c.encrypt(a) + c.encrypt(b)
is always equivalent to:
>>> c.encrypt(a+b)
That also means that you cannot reuse an object for encrypting or decrypting other data with the same key.
This function does not perform any padding.
- For MODE_ECB, MODE_CBC string length (in bytes) must be a multiple of block_size.
- For MODE_CFB, string length (in bytes) must be a multiple of segment_size/8.
- For MODE_CTR and MODE_OFB, string can be of any length.
Parameters: string (bytes) – The piece of data to encrypt.
Raises: - ValueError – When a mode of operation has be requested this code cannot handle.
- ValueError – When len(string) has a wrong length, as described above.
- TypeError – When the counter callable in CTR returns data with the wrong length.
Returns: The encrypted data, as a byte string. It is as long as string.
Return type:
-
encrypt_block
(key, block, **kwargs)¶ Dummy function for the encryption of a single block. Overwrite with ‘real’ encryption function.
Parameters: Raises: NotImplementedError – This method is to be overridden.
Returns: ciphertext block
Return type:
Block cipher mode of operation¶
Note
For mote details about different modes of operation, see Discussions/Block cipher mode of operation.
Block ciphers can be used in different modes of operation. The mode of operation can be set by passing one of the constants to the cipher object. Different modes of operation may require to pass extra arguments to the constructor.
Below is an example from the mostly PEP-272 compliant PyCryptodome.
>>> from Crypto.Cipher import AES
>>> iv = b'random 16 bytes!'
>>> key = b'0123456789abcdef'
>>> cipher = AES.new(key, mode=AES.MODE_CBC, IV=iv)
>>> cipher.encrypt(b'\00'*16)
b'j\xa2\xb5\x80\xf7\xbd\xb4I\xda\xea\x9aN\x9d\xb5\x9a\x17'
This library supports following modes of operation:
- Electronic code book (ECB)
- Cipher Block Chaining (CBC)
- Cipher Feedback (CFB)
- Output Feedback (OFB)
- Counter (CTR)
The CFB variant of PGP is not supported.
Planned modes are (extending to PEP-272):
- Propagating Cipher Block Chaining (PCBC), used in older Kerberos versions
- Infinite Garble Extension (IGE), used by Telegram.
- OpenPGP mode, compatible to PyCrypto or PyCryptodome.
Authenticated encryption (AE) or authenticated encryption with associated data (AEAD) are currently not supported, as they would require additional methods to finalize the encryption and sometimes have special requirements.
Constant | Number | Source | Implemented | Specification |
---|---|---|---|---|
MODE_ECB |
1 | PEP-272 | Yes | NIST.SP.800-38A |
MODE_CBC |
2 | PEP-272 | Yes | NIST.SP.800-38A |
MODE_CFB |
3 | PEP-272 | Yes | NIST.SP.800-38A |
MODE_PGP |
4 | PEP-272 | No | RFC 4880 |
MODE_OFB |
5 | PEP-272 | Yes | NIST.SP.800-38A |
MODE_CTR |
6 | PEP-272 | Yes | NIST.SP.800-38A |
MODE_OPENPGP |
7 | PyCrypto | No | RFC 4880 |
MODE_XTS |
8 | PyCryptoPlus | No | IEEE P1619 and NIST.SP.800-38E |
MODE_CCM |
8 | PyCrypto (unreleased) / PyCryptodome | No | NIST.SP.800-38C |
MODE_EAX |
9 | PyCrypto (unreleased) / PyCryptodome | No | The EAX Mode of Operation |
MODE_SIV |
10 | PyCrypto (unreleased) / PyCryptodome | No | RFC 5297 |
MODE_GCM |
11 | PyCrypto (unreleased) / PyCryptodome | No | NIST.SP.800-38D |
MODE_OCB |
12 | PyCrypto (unreleased) / PyCryptodome | No | RFC 7253 |
Utility functions¶
Utility library for compatibility with Python 2 and 3. A counter to use with CTR is also included.
There are versions of chr
and ord
-methods to work with bytes
with Python 3 and strings with Python 2.
-
class
pep272_encryption.util.
Counter
(nonce=None, initial_value=0, suffix=None, iv=None, IV=None, block_size=None, endian='big', wrap_around=False)¶ Counter for usage in CTR mode.
Big endian is as assumed for all counter operations by default.
Parameters: - nonce (bytes) – Prefix for counter operations.
- initial_value (int) – Initial integer value.
- suffix (bytes) – Suffix to add after output.
- iv (bytes) – Counter output to resume. The usage of iv prohibits the use of nonce, initial_value, block_size and suffix.
- IV (bytes) – Alternative for iv.
- block_size (int) – Size of counter in-/output
- endian (str) – Endian for number/byte conversions.
- wrap_around (bool) – If an exception should not be raised if the counter returns the same value twice. For security reasons, setting this value to true is not recommended.
The counter is not thread safe.
Without arguments, it generates a random nonce, with the counter starts at 0:
>>> c = Counter() # random nonce >>> c().endswith(b"\x00") True >>> c().endswith(b"\x01") True >>> c().endswith(b"\x02") True
Alternatively, a nonce and an initial value can be set:
>>> c = Counter(nonce=b'\x00\x01\x02', initial_value=0xff01, ... block_size=8) >>> c() b'\x00\x01\x02\x00\x00\x00\xff\x01' >>> c() b'\x00\x01\x02\x00\x00\x00\xff\x02'
The third alternative is to give a full start string. Counter length is determined by the IV length:
>>> c = Counter(IV=b'\x00'*4, endian="little") >>> c() b'\x00\x00\x00\x00' >>> c() b'\x01\x00\x00\x00'
-
block_size
= 16¶ Used by many algorithms
-
pep272_encryption.util.
b_chr
(ordinal)¶ Return a byte string of one character with 0 <= ordinal <= 255.
Parameters: ordinal (int) – The Unicode code point of a single char Returns: The byte string representation of the ordinal Return type: bytes
-
pep272_encryption.util.
b_ord
(byte)¶ Return the Unicode code point for a byte or iteration product of a byte string alike object (e.g. bytearray).
Parameters: byte (bytes or str or int) – The single byte or iteration product of a byte string to convert Returns: Unicode code point Return type: int
-
pep272_encryption.util.
from_bytes
(bytestring, byteorder)¶ Convert a bytestring to an interger.
Parameters: Return type:
-
pep272_encryption.util.
split_blocks
(bytestring, block_size)¶ Splits bytestring in block_size-sized blocks.
Raises an error if len(string) % blocksize != 0.
-
pep272_encryption.util.
to_bytes
(integer, length, byteorder)¶ Convert an integer to a bytestring.
Parameters: Return type: