HomePROJECTS

Cybersecurity Fundamentals 3

We will explore Cryptography πŸ”‘!
Nov 15 2024
15 min readβ€’Helpdesk, Hacking
Cybersec 3

Cybersecurity Fundamentals (Part 3)

Β 

🚨 WARNING 🚨: This will be one of the longest and somewhat advanced entries, I recommend reading carefully and if you put anything seen here into practice, you should do so at your own risk. Difficulty Level: ⭐⭐⭐

I recommend you go to the CheatSheet for a more dynamic and fun version of learning these terms. Click to find the Complete CheatSheet

Β 

What is Cryptography? πŸ”‘

CRYPTOGRAPHY: It is the art of representing information through symbols and coding systems to transmit information securely and reliably. What is its use?: To encrypt confidential or private information to keep it safe from any type of attack and to comply with information security regulations (although this is not always infallible).

Examples in your daily life

  • 🏠 When you log into your favorite social network with your password.
  • 🏠 When you unlock your cell phone.
  • 🏠 When you send a WhatsApp message to your partner.
  • 🏠 When you hear a taxi driver talking to another in code, for example: 10-4, 7-40, etc.

Β 

1. Symmetric Cryptography

  • πŸ’« Features: In symmetric cryptography, the same key is used to encrypt and decrypt a message. This requires both parties to share the key securely before use. It is faster compared to asymmetric cryptography and is used to encrypt large volumes of data.
  • πŸ’« Applications: It is commonly used for file encryption (for example, in cloud storage systems), in databases to protect sensitive data, and in virtual private networks (VPNs) to ensure data transmission, in short, large volumes of data.

Examples of Symmetric Cryptography

NameDescription
🐦 AES(Advanced Encryption Standard) It is a widely used standard for its efficiency and security. Some software that uses it are Encrypto, GIE, PassPai
🐦 DES(Data Encryption Standard) It is an older algorithm that has been largely replaced by AES.
🐦 BlowfishIt is a block cipher algorithm that is fast and efficient for variable-sized data, widely used in WooCommerce.

Β 

Symmetric Cryptography Code Example

#JSX
1import * as crypto from 'crypto';
2import { createReadStream, createWriteStream, PathLike } from 'fs';
3import { pipeline } from 'stream';
4
5const cipher = (
6  password: string,
7  salt: string,
8  size: 128|192|256,
9  input: PathLike,
10  output: PathLike,
11) => {
12  const cipher = crypto.createCipheriv(
13    `aes-${size}-cbc`,
14    crypto.scryptSync(password, salt, size / 8),
15    new Uint8Array(16)
16  );
17
18  pipeline(createReadStream(input), cipher, createWriteStream(output), (error)=> {
19    if(error) throw error;
20  });
21};
22

This TypeScript code snippet defines a function called cipher that performs encryption using the Advanced Encryption Standard (AES) algorithm.

The function receives the following parameters:

  • password: A string representing the password used to encrypt the data.
  • salt: A string representing the salt used in the encryption process.
  • size: A number representing the key size (128, 192, or 256).
  • input: A PathLike object representing the path to the file to be encrypted.
  • output: A PathLike object representing the path to the encrypted output file.

Inside the function, it creates a cipher using the createCipheriv method of the crypto module. It specifies the encryption algorithm as aes-{size}-cbc, where {size} is the value of the size parameter. It also generates a key using the scryptSync method, passing the password, salt, and size / 8 as arguments.

Next, the function uses the pipeline method to read the contents of the input file, encrypt it using the cipher, and write the encrypted result to the output file. If an error occurs during the encryption process, it throws the error.

#JSX
1import * as crypto from 'crypto';s
2import { createReadStream, createWriteStream, PathLike } from 'fs';
3import { pipeline } from 'stream';
4
5const decipher = (
6  password: string,
7  salt: string,
8  size: 128|192|256,
9  input: PathLike,
10  output: PathLike,
11) => {
12  const decipher = crypto.createDecipheriv(
13    `aes-${size}-cbc`,
14    crypto.scryptSync(password, salt, size / 8),
15    new Uint8Array(16)
16  );
17
18  pipeline(createReadStream(input), decipher, createWriteStream(output), (error) => {
19    if(error) throw error;
20  });
21};
22
23export default decipher;
24

This decrypts the content of the previous code.

Β 

2. Asymmetric or Public Key Cryptography

  • πŸ’« Features: Also known as public key cryptography, it uses a pair of keys: a public one and a private one. The public key can be shared openly, while the private key is kept secret. This technique allows both encryption and digital signing of messages.
  • πŸ’« Applications: It is essential for creating digital signatures, establishing secure sessions on the Internet (as in SSL/TLS for secure websites), and in encrypted email systems. This method is essential for establishing secure connections on the internet, such as in the HTTPS protocol.

Examples of Asymmetric Cryptography

NameDescription
🐦 RSA(Rivest-Shamir-Adleman) It is one of the first asymmetric cryptography systems, used for encryption and digital signatures.
🐦 DSA(Digital Signature Algorithm) Used mainly for creating digital signatures.
🐦 ECC(Elliptic Curve Cryptography) It offers the same security as RSA but with shorter keys, which makes it more efficient. Some software that uses it are GIE.

Β 

Asymmetric Cryptography Code Example

#JSX
1// Import necessary modules
2import * as crypto from "crypto";
3import { PathLike, mkdirSync, writeFileSync } from "fs";
4import { join } from "path";
5
6// Function to generate an RSA or RSA-PSS key pair
7const keygen = (
8  // Type of key to generate ("rsa" or "rsa-pss")
9  type: "rsa" | "rsa-pss",
10  // Encryption size for the private key (128, 192, or 256 bits)
11  size: 128 | 192 | 256,
12  // Passphrase to protect the private key
13  passphrase: string,
14  // Output format of the keys ("pem" or "der")
15  format: "pem" | "der",
16  // Modulus length for the key (2048, 3072, or 4096 bits)
17  modulusLength: 2048 | 3072 | 4096
18  // Define key generation options according to the type
19) => {
20  switch (type) {
21    case "rsa": {
22      // Options for RSA keys
23      const options: crypto.RSAKeyPairOptions<
24        crypto.KeyFormat,
25        crypto.KeyFormat
26      > = {
27        modulusLength, // Modulus length
28        publicKeyEncoding: {
29          type: "spki", // Standard format for public key
30          format, // Output format
31        },
32        privateKeyEncoding: {
33          type: "pkcs8", // Standard format for private key
34          format, // Output format
35          cipher: `aes-${size}-cbc`, // Encryption algorithm for the private key
36          passphrase, // Passphrase
37        },
38      };
39      return crypto.generateKeyPairSync("rsa", options); // Generate the key pair
40    }
41    case "rsa-pss": {
42      // Options for RSA-PSS keys (similar to RSA but with PSS signature)
43      const options: crypto.RSAPSSKeyPairOptions<
44        crypto.KeyFormat,
45        crypto.KeyFormat
46      > = {
47        modulusLength, // Modulus length
48        publicKeyEncoding: {
49          type: "spki", // Standard format for public key
50          format, // Output format
51        },
52        privateKeyEncoding: {
53          type: "pkcs8", // Standard format for private key
54          format, // Output format
55          cipher: `aes-${size}-cbc`, // Encryption algorithm for the private key
56          passphrase, // Passphrase
57        },
58      };
59      return crypto.generateKeyPairSync("rsa-pss", options);  // Generate the key pair
60    }
61  }
62};
63
64// Function to create a key pair and save them to files
65const keypair = (
66  type: "rsa" | "rsa-pss",
67  size: 128 | 192 | 256,
68  passphrase: string,
69  outDir: string,
70  outFormat: "pem" | "der",
71  modulusLength: 2048 | 3072 | 4096
72) => {
73  // Generate the key pair using the keygen function
74  const { publicKey, privateKey } = keygen(
75    type,
76    size,
77    passphrase,
78    outFormat,
79    modulusLength
80  );
81  // Create the output folder if it does not exist
82  mkdirSync(outDir, { recursive: true });
83  // Save the public key to a file
84  writeFileSync(join(outDir, `public.${outFormat}`), publicKey.toString());
85  // Save the private key to a file (encrypted with the passphrase)
86  writeFileSync(join(outDir, `private.${outFormat}`), privateKey.toString());
87};
88
89// Export the keypair function to use it in other modules
90export default keypair;
91
92

The above code is a TypeScript function called keygen that generates an RSA or RSA-PSS key pair. It takes five parameters:

  • type: the type of key to generate, either "rsa" or "rsa-pss".
  • size: the encryption size of the private key (128, 192, or 256 bits)
  • Passphrase: password to protect the private key.
  • format: the output format of the keys ("pem" or "der")
  • modulusLength: the modulus length of the key (2048, 3072, or 4096 bits)

The function uses a switch statement to determine which type of key to generate, and then creates an options object with the specified parameters. It then calls the crypto.generateKeyPairSync function to generate the key pair, passing the options object.

In summary, this function generates an RSA or RSA-PSS key pair with customizable encryption size, password protection, output format, and modulus length.

Β 

3. Cryptographic Hash

  • πŸ’« Features: Cryptographic hashes are algorithms that take an input of any size and produce a fixed-size output, known as a hash. These are one-way, which means that the original message cannot be obtained from the hash. In addition, a small modification in the input produces a completely different hash.
  • πŸ’« Applications: They are used to verify data integrity, in password authentication (storing the hash of the password instead of the password itself), and in blockchain technology to ensure the integrity of the blockchain.

Examples of Cryptographic Hash

NameDescription
🐦 SHA-256(Secure Hash Algorithm 256 bits) Part of the SHA-2 family, widely used in applications such as Bitcoin.
🐦 MD5(Message-Digest Algorithm 5) Although it is fast, it is no longer recommended due to vulnerabilities found.
🐦 WhirlpoolA hash algorithm that produces a 512-bit hash.

Β 

Cryptographic Hash Code Example

#JSX
1import * as crypto from 'crypto';
2import { PathLike, readFileSync } from 'fs';
3
4const hash = (algorithm: string, encoding: crypto.BinaryToTextEncoding, input: PathLike) => {
5  return crypto.createHash(algorithm).update(readFileSync(input)).digest(encoding); 
6};
7
8export default hash;
9
10

This is a TypeScript function called hash that generates a hash value for a given file. It takes three parameters:

  • algorithm: the hash algorithm to use (e.g. "sha256", "md5", etc.)
  • encoding: the encoding to use for the resulting hash value (e.g. "hex", "base64", etc.)
  • input: the file for which the hash will be generated

The function uses the crypto module to create a hash object, updates it with the contents of the input file, and returns the hash value in the specified encoding.

Β 

4. Elliptic Curve Cryptography

  • πŸ’« Features: Based on the arithmetic of elliptic curves over finite fields, it offers a high level of security with shorter keys compared to traditional asymmetric cryptography. This translates into faster operations and lower resource usage.
  • πŸ’« Applications: It is widely used in mobile applications and devices with limited resources. It is also essential in the creation of cryptocurrencies, such as Bitcoin and Ethereum, to secure transactions and manage private keys.

Examples of Elliptic Curve

NameDescription
🐦 ECDSA(Elliptic Curve Digital Signature Algorithm) Used to create digital signatures.
🐦 ECDH(Elliptic Curve Diffie-Hellman) A method for exchanging secret keys.

Β 

Elliptic Curve Code Example

#PYTHON
1from cryptography.hazmat.primitives.asymmetric import x25519
2from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey, X25519PublicKey
3from cryptography.hazmat.primitives import serialization, hashes
4from cryptography.hazmat.primitives.asymmetric import padding
5from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
6from cryptography.hazmat.backends import default_backend
7import os
8import math
9
10
11def generate_key_pair():
12    # Generates an ECDH key pair.
13    private_key = X25519PrivateKey.generate()
14    public_key = private_key.public_key()
15    return private_key, public_key
16
17
18def derive_key(private_key, public_key):
19    # Obtaining a shared key through ECDH
20    shared_key = private_key.exchange(public_key)
21    return shared_key
22
23
24def fibonacci_sequence(n):
25    # Generate a Fibonacci sequence up to the nth term.
26    sequence = [0, 1]
27    while len(sequence) < n:
28        sequence.append(sequence[-1] + sequence[-2])
29    return sequence
30
31
32def xor_encrypt(data, key):
33    # XOR the data with the key.
34    return bytes([b ^ key[i % len(key)] for i, b in enumerate(data)])
35
36
37def encrypt(plaintext, public_key):
38    # Encrypt the plaintext using the public key and a Fibonacci sequence.
39    # Generates an asymmetric key randomly
40    symmetric_key = os.urandom(32)
41
42    # The shared key is obtained through ECDH
43    private_key, _ = generate_key_pair()  # Generates a temporary private key
44    shared_key = derive_key(private_key, public_key)
45
46    # Generates a fibonacci key based on the length of the plaintext
47    fib_sequence = fibonacci_sequence(len(plaintext))
48
49    # Adjusts the length of the combined key to match the plaintext
50    combined_key = bytes(
51        [shared_key[i % len(shared_key)] ^ fib_sequence[i % len(fib_sequence)] for i in range(len(plaintext))])
52
53    # Encrypts the plaintext with the combined key
54    encrypted_text = xor_encrypt(plaintext.encode(), combined_key)
55
56    return encrypted_text, private_key  # Temporarily returns the private key
57
58
59def decrypt(encrypted_text, private_key, public_key):
60    """Decrypts the ciphertext using the private key and the public key."""
61    # The shared key is obtained through ECDH
62    shared_key = derive_key(private_key, public_key)
63
64    # Generate a Fibonacci sequence based on the length of the ciphertext
65    fib_sequence = fibonacci_sequence(len(encrypted_text))
66
67    # Adjusts the length of the combined key to match the ciphertext
68    combined_key = bytes(
69        [shared_key[i % len(shared_key)] ^ fib_sequence[i % len(fib_sequence)] for i in range(len(encrypted_text))])
70
71    # Decrypts the ciphertext with the combined key
72    decrypted_text = xor_encrypt(encrypted_text, combined_key)
73
74    return decrypted_text.decode(errors='ignore')  # Ignores errors during decoding
75
76
77print("Enter a password to encrypt")
78
79passwd = input(": ")
80
81# Example of use
82# Phrase: --
83plaintext = passwd
84private_key, public_key = generate_key_pair()
85encrypted_text, temp_private_key = encrypt(plaintext, public_key)
86print(f"Encrypted: {encrypted_text}")
87
88decrypted_text = decrypt(encrypted_text, temp_private_key, public_key)
89print(f"Decrypted: {decrypted_text}")
90
91

The above code was written in Python using calculation techniques using elliptic curve cryptography (specifically, the X25519 curve).

Install the dependencies and make sure to install the cryptography library correctly.

Example: We enter the word: Hello

Key generation process

  1. Private key: It is a randomly generated value that is kept secret. It is generated using the X25519PrivateKey.generate() method.
  2. Public key: It is derived from the private key and can be shared openly. It is calculated as part of the key pair generation process.

Key generation example

  1. Run the generate_key_pair() function to create a private key and a public key.
  2. The private key is a binary value that is not intended to be shared.
  3. The public key is derived from the private key and can be shared with others.

Example of output

If you were to run the program, you might see a result similar to this (the actual values will be different each time due to randomness):

  • Private Key: b'\x1a\x2b\x3c\x4d\x5e\x6f\...'
  • Public Key: b'\x9a\x8b\x7c\x6d\x5e\x4f\...'

Important note

The public and private keys are not derived from the "Hello" input, but are generated independently. The input is only used for the encryption and decryption processes after the keys have been generated.

Β 

5. Quantum Cryptography

  • πŸ’« Features: It takes advantage of the principles of quantum mechanics, such as quantum entanglement and uncertainty, to create communication systems that cannot be intercepted without being detected. It offers theoretically unconditional security.
  • πŸ’« Applications: Although it is still in the early stages of development and implementation, it has the potential to revolutionize security in sensitive communications and in protection against the threats of quantum computing to traditional cryptography.

Examples of Quantum Cryptography

NameDescription
🐦 QKD(Quantum Key Distribution) It allows two parties to generate a shared secret key using quantum particles. If a third party tries to intercept the key, this will alter the quantum state and will be detectable.

This is still under development, but the main idea of quantum cryptography promises to revolutionize computer security by offering methods that are theoretically invulnerable to future attacks based on quantum computers

Quantum Cryptography Code Example

#PYTHON
1import numpy as np
2import random
3
4class QKD:
5    def __init__(self, n_bits):
6        self.n_bits = n_bits
7        self.alice_bits = []
8        self.bob_bits = []
9        self.bases_alice = []
10        self.bases_bob = []
11        self.shared_key = []
12
13    def generate_bits_and_bases(self):
14        # Alice generates random bits and bases
15        for _ in range(self.n_bits):
16            self.alice_bits.append(random.randint(0, 1))  # Random bit (0 or 1)
17            self.bases_alice.append(random.choice(['H', 'V']))  # Random basis (horizontal or vertical)
18
19    def simulate_bob_measurement(self):
20        # Bob randomly chooses bases to measure Alice's bits
21        for _ in range(self.n_bits):
22            self.bases_bob.append(random.choice(['H', 'V']))
23            # Simulate the measurement (if the bases match, he gets the bit)
24            if self.bases_alice[_] == self.bases_bob[_]:
25                self.bob_bits.append(self.alice_bits[_])
26            else:
27                self.bob_bits.append(None)  # No bit if the bases do not match
28
29    def sift_key(self):
30        # Sift the key based on the matching bases
31        for i in range(self.n_bits):
32            if self.bases_alice[i] == self.bases_bob[i]:
33                self.shared_key.append(self.alice_bits[i])
34
35    def run_qkd_protocol(self):
36        self.generate_bits_and_bases()
37        self.simulate_bob_measurement()
38        self.sift_key()
39        
40        return self.shared_key
41
42# Example of use
43n_bits = 10  # Number of bits to exchange
44qkd_protocol = QKD(n_bits)
45secure_key = qkd_protocol.run_qkd_protocol()
46
47print("Shared secure key:", secure_key)
48

This classification reflects the diversity and depth of the field of cryptography, showing how its different techniques are applied to protect information in various contexts. From message encryption to the security of online transactions and user authentication, cryptography is essential for security in the digital world.


Β 

Later I will show how these encryptions are broken and why md5 is very bad to use. In another entry we will review how AES encryption works.

Β 

Thanks for reading

Β 

Sources

Did you like this article? Share it!

Β© 2025