Get a Pentest and security assessment of your IT network.

Cyber Security

C++ Block Cipher Guide

TL;DR

This guide shows you how to implement a basic block cipher in C++. We’ll focus on the core concepts and provide code examples for encryption and decryption. It’s not production-ready (security is complex!), but it will help you understand how these ciphers work.

1. Understanding Block Ciphers

Block ciphers encrypt data in fixed-size blocks (e.g., 64 bits, 128 bits). Here’s a simplified overview:

  • Plaintext: The original message you want to encrypt.
  • Ciphertext: The encrypted message.
  • Key: A secret value used for encryption and decryption.
  • Block Size: The size of the data blocks processed at a time.

A basic block cipher involves these steps:

  1. Initialisation Vector (IV): Often used with chaining modes to make each encryption unique, even with the same key.
  2. Round Function: The core of the cipher – a series of operations that mix and transform the data.
  3. Key Schedule: Generates subkeys from the main key for use in each round.

2. Simple Example Cipher (Not Secure!)

We’ll create a very basic cipher for demonstration purposes. Do not use this in any real-world application! It’s vulnerable to many attacks.

2.1 Encryption Function

#include <iostream>
#include <string>

std::string encrypt(const std::string& plaintext, const std::string& key) {
  std::string ciphertext = "";
  for (size_t i = 0; i < plaintext.length(); ++i) {
    ciphertext += char((plaintext[i] + key[i % key.length()]) % 256);
  }
  return ciphertext;
}

This code simply adds the ASCII value of each character in the plaintext to the corresponding character in the key (modulo 256). The modulo operation ensures that the result stays within the valid range for a char.

2.2 Decryption Function

std::string decrypt(const std::string& ciphertext, const std::string& key) {
  std::string plaintext = "";
  for (size_t i = 0; i < ciphertext.length(); ++i) {
    plaintext += char((ciphertext[i] - key[i % key.length()] + 256) % 256);
  }
  return plaintext;
}

The decryption function subtracts the key from the ciphertext (again, modulo 256). Adding 256 before the modulo operation handles potential negative values.

2.3 Example Usage

int main() {
  std::string message = "Hello, world!";
  std::string key = "secretkey";

  std::string encryptedMessage = encrypt(message, key);
  std::cout << "Encrypted: " << encryptedMessage << std::endl;

  std::string decryptedMessage = decrypt(encryptedMessage, key);
  std::cout << "Decrypted: " << decryptedMessage << std::endl;

  return 0;
}

3. Improving the Cipher (Still Not Secure!)

The previous example is extremely weak. Here are some ways to improve it, though still not enough for real-world use:

  • Larger Key Size: Use a longer key (e.g., 128 bits or more).
  • Multiple Rounds: Repeat the encryption process multiple times with different subkeys generated from the main key.
  • Substitution and Permutation: Introduce substitution boxes (S-boxes) to replace parts of the data and permutation functions to rearrange it.

3.1 Example Round Function

// Very simplified round function - DO NOT USE IN PRODUCTION!
unsigned char round(unsigned char input, unsigned char subkey) {
  return (input ^ subkey) * 2 + 1;
}

4. Key Schedule

The key schedule generates a series of subkeys from the main key for each round of encryption.

4.1 Simple Key Schedule Example

std::vector<unsigned char> generateSubkeys(const std::string& key, int numRounds) {
  std::vector<unsigned char> subkeys;
  for (int i = 0; i < numRounds; ++i) {
    subkeys.push_back(key[i % key.length()]);
  }
  return subkeys;
}

5. Chaining Modes

Chaining modes help to encrypt data more securely by making each block dependent on the previous one.

  • ECB (Electronic Codebook): Each block is encrypted independently – vulnerable to pattern recognition.
  • CBC (Cipher Block Chaining): Each block is XORed with the previous ciphertext before encryption. Requires an Initialisation Vector (IV).

6. Important Considerations for cyber security

  • Never roll your own crypto: Use well-vetted libraries like OpenSSL or Crypto++.
  • Understand the risks: Block cipher implementation is complex and prone to errors.
  • Key Management: Securely store and manage encryption keys.
Related posts
Cyber Security

Zip Codes & PII: Are They Personal Data?

Cyber Security

Zero-Day Vulnerabilities: User Defence Guide

Cyber Security

Zero Knowledge Voting with Trusted Server

Cyber Security

ZeroNet: 51% Attack Risks & Mitigation