Symmetric key cryptography
Die Seite is noch nich übersetzt. Se kieken die englische Originalversion.
In this lesson we will look at symmetric key cryptography which secures much of the data at rest and in transit by virtue of its efficiency.
By the end of the lesson we will have covered:
- What symmetric key cryptography is
- Python code examples demonstrating the use of symmetric key cryptography
- A look at applications of symmetric key cryptography
- Symmetric key cryptography applications
- The security of symmetric key cryptography
- Threats to these algorithms from both classical and quantum computers
Introduction to symmetric key cryptography
Symmetric key cryptography (SKC) is the oldest and most intuitive form of cryptography. With SKC, confidential information is secured through symmetric key encryption (SKE), that is, by using a single secret key for both encryption and decryption.
SKC involves:
- An encryption function that converts a given plain text instance to ciphertext while utilizing a secret key
- A decryption function that inverts the operation by converting the ciphertext back to plain text using the same secret key
Plain text can mean any kind of unencrypted data such as natural language text or binary code whose information content is in principle directly accessible, while ciphertext refers to encrypted data whose information content is intended to be inaccessible prior to decryption.
An algorithm that describes the encryption and decryption operations using a shared secret key is also called a symmetric cipher.

Figure 1. Symmetric key encryption of a given plain text to ciphertext and decryption back to plain text using the same key.
Properties of symmetric key cryptosystems
A symmetric key cryptosystem should ensure the following properties to secure messages-both statically stored data and/or communications over some transmission channel:
- Confidentiality: Refers to the property that the information content of encrypted messages is protected from unauthorized access.
- Integrity: Refers to the property that any tampering of encrypted messages during storage or transmission can be detected.
- Authenticity: Refers to the property that the receiver of a message can verify the identity of the sender and detect impersonation by an unauthorized party.
Furthermore, these properties should be realized in a setting where the algorithms or ciphers used for encryption and decryption may be public and where access to the information content of encrypted messages is controlled exclusively through access to the secret key.
Implementing a secure symmetric key cryptosystem therefore involves two main tasks:
- Employing a robust symmetric key encryption algorithm resistant to cryptographic attacks.
- Ensuring confidentiality in the distribution and management of secret keys.
In this lesson, we will discuss aspects related to the first task, which forms the primary concern of SKC technology. The second task, however, needs solutions that fall outside of SKC itself and will be introduced later.
Illustration of symmetric key encryption using python
We show a simple example of the encrypt and decrypt operations using the classical Caesar shift cipher and the modern Advanced Encryption System (AES), which has been the standard for symmetric key encryption since 2001. First we set up some Python libraries that provide the needed symmetric key encryption ciphers, and then define the plain text we wish to encrypt.
# Added by doQumentation — required packages for this notebook
!pip install -q cryptography numpy secretpy
# Install the library if needed
# %pip install secretpy
# import the required crypto functions which will be demonstrated later
from secretpy import Caesar
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from functools import reduce
import numpy as np
# Set the plaintext we want to encrypt
plaintext = "this is a strict top secret message for intended recipients only"
print(f"\nGiven plaintext: {plaintext}")
We will see how to encrypt and decrypt it using two different symmetric key encryption methods:
- The classic Caesar shift cipher
- The modern Advanced Encryption Standard AES-256 protocol
Caesar shift cipher:
Caesar shift encryption involves defining
- An alphabet of possible characters to encode
- A shift value which can be between 0 (unencrypted) and the length of the alphabet. We consider this the key.
It is known as a monoalphabetic substitution cipher since each letter of the plain text is substituted with another in the ciphertext.
In this example we will use lowercase letters of the alphabet.
Let's start by setting things up.
# initialize the required python object for doing Caesar shift encryption
caesar_cipher = Caesar()
# Define the shift, ie the key
caesar_key = 5
print(f"Caesar shift secret key: {caesar_key}")
# Define the alphabet
alphabet = (
"a",
"b",
"c",
"d",
"e",
"f",
"g",
"h",
"i",
"j",
"k",
"l",
"m",
"n",
"o",
"p",
"q",
"r",
"s",
"t",
"u",
"v",
"w",
"x",
"y",
"z",
" ",
)
print(f"alphabet: {alphabet}")
Encrypt the plain text to get ciphertext for the Caesar cipher.
caeser_ciphertext = caesar_cipher.encrypt(plaintext, caesar_key, alphabet)
print(f"Encrypted caeser shift ciphertext: {caeser_ciphertext}")
Decrypt the ciphertext back to the original plain text using the same key used for encryption.
caeser_plaintext = caesar_cipher.decrypt(caeser_ciphertext, caesar_key, alphabet)
print(f"Decrypted caeser shift plaintext: {caeser_plaintext}\n")
Advanced encryption standard (AES) cipher
We now encrypt the plain text using AES, a popular symmetric key encryption algorithm.
We start by creating the key, in this case, a random 16-letter string.
# lambda defines an inline function in this case that takes two values a,b with the resulting expression of a+b
# reduce uses a two-argument function(above), and applies this to all the entries in the list (random alphabet characters) cumulatively
aes_key = reduce(lambda a, b: a + b, [np.random.choice(alphabet) for i in range(16)])
print(f"AES secret key: {aes_key}")
AES supports multiple operating modes and requires we specify which to use.
We choose the Cipher Block Chaining (CBC) mode provided by the modes.CBC class of the cryptography library. The CBC mode of AES uses randomness for additional security. This requires specifying a random Initialization Vector (IV), also called a nonce. We will use a random string for this as well, just like we did for the key.
aes_initialization_vector = reduce(
lambda a, b: a + b, [np.random.choice(alphabet) for i in range(16)]
)
print(f"AES initialization vector: {aes_initialization_vector}")
We can now instantiate an AES cipher on behalf of the sender of the secret message. Note that the initialization vector is passed to the modes.CBC class to set up the CBC mode of operation.
We will then encrypt the plain text to send.
# The encryptor is setup using the key and CBC. In both cases we need to convert the string (utf-8) into bytes
sender_aes_cipher = Cipher(
algorithms.AES(bytes(aes_key, "utf-8")),
modes.CBC(bytes(aes_initialization_vector, "utf-8")),
)
aes_encryptor = sender_aes_cipher.encryptor()
# update can add text to encypt in chunks, and then finalize is needed to complete the encryption process
aes_ciphertext = (
aes_encryptor.update(bytes(plaintext, "utf-8")) + aes_encryptor.finalize()
)
# Note the output is a string of bytes
print(f"Encrypted AES ciphertext: {aes_ciphertext}")
To decrypt it, let us instantiate an AES cipher on behalf of the receiver. Note that the intended receiver has access to both the secret key and the initialization vector, but the latter is not required to be secret.
# Similar setup of AES to what we did for encryption, but this time, for decryption
receiver_aes_cipher = Cipher(
algorithms.AES(bytes(aes_key, "utf-8")),
modes.CBC(bytes(aes_initialization_vector, "utf-8")),
)
aes_decryptor = receiver_aes_cipher.decryptor()
# Do the decryption
aes_plaintext_bytes = aes_decryptor.update(aes_ciphertext) + aes_decryptor.finalize()
# convert back to a character string (we assume utf-8)
aes_plaintext = aes_plaintext_bytes.decode("utf-8")
print(f"Decrypted AES plaintext: {aes_plaintext}")
Applications of symmetric key cryptography
While classical ciphers such as the Caesar cipher fell out of use a long time ago, modern symmetric cryptosystems such as AES are deployed in a wide range of applications, including:
-
Data encryption and decryption: SKC is widely used to protect sensitive data, whether statically stored on a device or transmitted over a network. Examples include protecting user credentials, encrypting email messages, and securing financial transactions, among others.
-
Secure communication: Common communication protocols such as SSL/TLS use a combination of symmetric and asymmetric key encryption to ensure the confidentiality and integrity of data exchanged between two parties. These messages are encrypted and decrypted using symmetric key encryption which uses a shared key. The key used in symmetric key encryption is securely exchanged using asymmetric key encryption which uses a public-private key pair. Symmetric key encryption is much faster and hence can be used for encryption of messages of large size.
-
Authenticity verification: In some settings, SKC is employed through techniques like message authentication codes (MACs) and keyed-hash MACs (HMAC) to verify the authenticity and integrity of messages, ensuring tamper-resistant communication.
-
File and disk encryption: Full-disk encryption software and file encryption tools employ SKC to protect sensitive data stored on hard disks or portable storage devices.
-
Virtual private networks: VPN technologies, which aim to provide confidential communication channels free from eavesdropping, can use symmetric or asymmetric key encryption to connect remote users as well as corporate networks.
The diverse array of applications in which SKC is deployed in turn require that symmetric cryptosystems satisfy a certain set of criteria.
Principles of symmetric key encryption
In this section, we will discuss some of the basic principles underlying the security of symmetric key encryption algorithms.
Resistance to brute force attack: The most basic requirement for the security of an encryption cipher is that the key space size — in other words, the number of possible distinct keys from which someone using the algorithm could have chosen — is very large.
Resistance to cryptanalytic attack: The second basic requirement for a cipher, symmetric or otherwise, is that it can generate ciphertexts that are informationally inscrutable. To this end, a necessary but not sufficient condition from an information theory perspective is that ciphertexts should be characterized by high entropy, making them indistinguishable from random text with no discernible patterns or correlations. This way, an attacker can gain no information about the plain text or secret key by trying to analyze the ciphertext using frequency analysis or other statistical techniques.
Resistance to general forms of cryptanalytic attacks sufficient to ensure semantic security is formalized via the notion of indistinguishability. While there are several variants of indistinguishability with distinct requirements, a symmetric cryptosystem is considered to be semantically secure if it satisfies the criterion of Indistinguishability under Chosen Plain Text Attack (IND-CPA). This means that an attacker cannot distinguish between the encryptions of two different messages even if allowed to send multiple plain texts of their choosing to the algorithm and view the corresponding ciphertexts.
As we will consider later, IND-CPA typically requires the use of randomness to ensure that each time a given plain text is encrypted with a given secret key, the resulting ciphertext is unpredictably different for each encryption.
Failure modes of classical ciphers: Before the advent of modern cryptography in the 1970s, most classical ciphers in practical use failed to satisfy one or both above requirements. For instance, early substitution ciphers such as the monoalphabetic Caesar shift cipher were characterized by both a small key space size (see Table 1) and low entropy ciphertext, making them insecure against a variety of cryptanalytic attacks such as brute force attacks, frequency analysis, and known-plain-text (KPT) attacks.
Subsequent polyalphabetic substitution ciphers such as the Vigenère cipher and the Enigma machine cipher featured effectively large key space sizes, making them resistant to brute force attacks, but they were susceptible to frequency analysis and KPT attacks, respectively. Similarly to substitution ciphers, classic transposition ciphers, which rearrange letters in a message instead of substituting them, are also compromised by a variety of attacks such as anagramming, statistical analysis, brute force, and KPT attacks, among others.
Theoretically, a polyalphabetic substitution cipher known as the one-time pad (OTP) is known to be cryptographically secure. An OTP features a secret key that should be (1) composed of randomly chosen letters or bits, (2) at least as long as the original plain text, and (3) used only once. An OTP is impractical for actual applications because if the secret key — which is required to be as long as the plain text and can be used only once — could be shared securely, then so could the original plain text. The OTP instead illustrates the utility of randomness in generating secure ciphertexts.
An attacker trying to implement a brute force search through the key space to find a key that decrypts the message has to perform a number of operations proportional to the key space size.
Therefore, a large key space size provides resistance against brute force attacks by rendering them computationally infeasible. Table 1 lists the key space sizes of some well-known ciphers.