Skip to content

Commit

Permalink
crypto additions
Browse files Browse the repository at this point in the history
  • Loading branch information
breezy-codes committed Dec 5, 2024
1 parent 15e3098 commit 4b72580
Show file tree
Hide file tree
Showing 7 changed files with 780 additions and 166 deletions.
1 change: 0 additions & 1 deletion _toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ parts:
- file: maths/number-theory/converting-values
- file: maths/modular-arithmetic/mod-arith-intro
sections:
- file: maths/modular-arithmetic/modular-arithmetic
- file: maths/modular-arithmetic/modular-addition
- file: maths/modular-arithmetic/modular-subtraction
- file: maths/modular-arithmetic/modular-multiplication
Expand Down
2 changes: 1 addition & 1 deletion ciphers/base64.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"\n",
"Encoding data with Base64 involves converting the input data into a sequence of characters from the Base64 character set. This process ensures that the data can be safely transmitted over text-based protocols such as HTTP or email. The following code shows how you can implement Base64 encoding to convert a message into a Base64-encoded string.\n",
"\n",
"```{admonition} Interesting Fact\n",
"```{admonition} Handy Tip\n",
":class: tip\n",
"The Base64-encoded message is padded with `=` characters to ensure that the length is a multiple of 4.\n",
"```"
Expand Down
559 changes: 537 additions & 22 deletions maths/number-theory/converting-values.ipynb

Large diffs are not rendered by default.

225 changes: 172 additions & 53 deletions steganography/bitmap-caesar.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -34,44 +34,55 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"## Encode\n",
"## Encoding with Caesar Cipher and Base64\n",
"\n",
"Here’s how the process works:\n",
"\n",
"<Steps>\n",
"1. **Plaintext Message:** Start with the original message (e.g., `\"im a cat\"`).\n",
"2. **Apply Caesar Cipher:** Obfuscate the message using a chosen shift value (e.g., `3`). The message `\"im a cat\"` might become `\"lp d fdw\"`.\n",
"3. **Encode in Base64:** Convert the obfuscated message into Base64, producing a string of printable characters.\n",
"4. **Embed in Image:** Use LSB steganography to embed the Base64-encoded string into the image.\n",
"</Steps>\n",
"\n",
"To extract and interpret the message, the reverse process is followed:\n",
"\n",
"<Steps>\n",
"1. **Extract the Base64 Message:** Decode the embedded Base64 string from the image.\n",
"2. **Decrypt Caesar Cipher:** Apply the inverse Caesar Cipher shift to recover the original plaintext message.\n",
"</Steps>\n",
"\n",
"By combining Caesar Cipher obfuscation with LSB steganography, you can enhance the security of your hidden messages while exploring the principles of encryption and steganography. Here is how you can implement this in your code:\n",
"\n",
":::note\n",
"You will need to update the path to be the path to your bitmap file.\n",
":::"
"```{admonition} Note\n",
":class: note\n",
"You may need to update the `path` variable to point to the image you want to use.\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "plaintext"
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Enter the message to embed: \n",
"Hi! I'm a cool cat!\n",
"Enter the Caesar cipher shift value: \n",
"18\n",
"Caesar cipher shifted message: Za! A'e s uggd usl!\n",
"Base64-encoded message: WmEhIEEnZSBzIHVnZ2QgdXNsIQ==\n",
"Base64 length (in characters): 28\n",
"Binary message: 01010111011011010100010101101000010010010100010101000101011011100101101001010011010000100111101001001001010010000101011001101110010110100011001001010001011001110110010001011000010011100111001101001001010100010011110100111101\n",
"Length bits: 00000000000000000000000000011100\n",
"\n",
"Original binary data at embedding positions (truncated):\n",
"0110011[1]10001110010000100110011[1]10001110010000100110011[1]10...0110011[1]1000111[0]0100001[0]011001111000111[0]0100001001100111\n",
"\n",
"Modified binary data at embedding positions (truncated):\n",
"0110011[0]10001110010000100110011[0]10001110010000100110011[0]10...0110011[0]1000111[1]0100001[1]011001111000111[1]0100001001100111\n",
"Message embedded successfully in Base64! Encoded image saved as /run/media/breezy/b1de4ffb-fd5e-4613-986d-b119a4c02043/GitHub/Jupyter-Books/cryptography-guide/steganography/hiddencat.bmp.\n"
]
}
},
"outputs": [],
],
"source": [
"import os\n",
"\n",
"path = \"PATH TO YOUR FOLDER HERE\"\n",
"path = os.getcwd()\n",
"\n",
"def ceaser_cipher_encode(input_string, shift):\n",
" encoded_string = \"\"\n",
Expand Down Expand Up @@ -175,9 +186,11 @@
"\n",
"print(\"Enter the message to embed: \")\n",
"message_to_embed = input()\n",
"print(f\"{message_to_embed}\")\n",
"\n",
"print(\"Enter the Caesar cipher shift value: \")\n",
"shift_value = int(input())\n",
"print(f\"{shift_value}\")\n",
"\n",
"# Specify the offset where the pixel data starts (e.g., 54 for standard BMP)\n",
"pixel_data_offset = int.from_bytes(data[10:14], byteorder='little')\n",
Expand All @@ -192,61 +205,167 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"### Expected Output\n",
"\n",
"After extracting the message and decrypting it using the Caesar Cipher, you'll see an output like:\n",
"\n",
"```shell\n",
"Enter the message to embed: \n",
"im a cat \n",
"Enter the Caesar cipher shift value: \n",
"8\n",
"Caesar cipher shifted message: qu i kib\n",
"Base64-encoded message: cXUgaSBraWI=\n",
"Base64 length (in characters): 12\n",
"Binary message: 011000110101100001010101011001110110000101010011010000100111001001100001010101110100100100111101\n",
"Length bits: 00000000000000000000000000001100\n",
"\n",
"Original binary data at embedding positions (truncated):\n",
"0011100[1]00100100000101100001011[1]011111101100000[1]0000101[1]...100110001111001[0]0010000[0]0101111[0]1000110[0]0000110010100101\n",
"\n",
"Modified binary data at embedding positions (truncated):\n",
"0011100[0]00100100000101100001011[0]011111101100000[0]0000101[0]...100110001111001[1]0010000[1]0101111[1]1000110[1]0000110010100101\n",
"Message embedded successfully in Base64! Encoded image saved as /yourfolders/hiddencat.bmp.\n",
"```"
"The comparison between the original and modified binary data highlights the subtle but precise changes made during the embedding process. Notice how the least significant bits (LSBs) of the original binary data are modified to encode the length and content of the hidden message. These alterations are so minor that they do not visibly affect the image, yet they securely store the message within its pixel data. This clever manipulation of binary values demonstrates the power of steganography, where seemingly insignificant details carry meaningful information—hidden in plain sight. By preserving the image's integrity while embedding a secret, this technique showcases how technology can be used creatively to protect and communicate information."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Decode\n",
"## Decoding with Brute Force\n",
"\n",
"make one that brute forces"
"If you don't know the shift value used in the Caesar Cipher, you can try all possible shifts to decrypt the message. This is known as a **brute force attack** and is only feasible for small shift values. For each shift, you decode the Base64 message and check if it contains any recognisable text. If it does, you've found the correct shift value."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "plaintext"
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Length bits: 00000000000000000000000000011100\n",
"Extracted Base64 length (in characters): 28\n",
"Extracted Base64 message: WmEhIEEnZSBzIHVnZ2QgdXNsIQ==\n",
"Extracted Binary message: 01010111011011010100010101101000010010010100010101000101011011100101101001010011010000100111101001001001010010000101011001101110010110100011001001010001011001110110010001011000010011100111001101001001010100010011110100111101\n",
"Extracted message: Za! A'e s uggd usl!\n",
"Brute-forcing Caesar Cipher:\n",
"Shift 0 => Za! A'e s uggd usl!\n",
"Shift 1 => Yz! Z'd r tffc trk!\n",
"Shift 2 => Xy! Y'c q seeb sqj!\n",
"Shift 3 => Wx! X'b p rdda rpi!\n",
"Shift 4 => Vw! W'a o qccz qoh!\n",
"Shift 5 => Uv! V'z n pbby png!\n",
"Shift 6 => Tu! U'y m oaax omf!\n",
"Shift 7 => St! T'x l nzzw nle!\n",
"Shift 8 => Rs! S'w k myyv mkd!\n",
"Shift 9 => Qr! R'v j lxxu ljc!\n",
"Shift 10 => Pq! Q'u i kwwt kib!\n",
"Shift 11 => Op! P't h jvvs jha!\n",
"Shift 12 => No! O's g iuur igz!\n",
"Shift 13 => Mn! N'r f httq hfy!\n",
"Shift 14 => Lm! M'q e gssp gex!\n",
"Shift 15 => Kl! L'p d frro fdw!\n",
"Shift 16 => Jk! K'o c eqqn ecv!\n",
"Shift 17 => Ij! J'n b dppm dbu!\n",
"Shift 18 => Hi! I'm a cool cat!\n",
"Shift 19 => Gh! H'l z bnnk bzs!\n",
"Shift 20 => Fg! G'k y ammj ayr!\n",
"Shift 21 => Ef! F'j x zlli zxq!\n",
"Shift 22 => De! E'i w ykkh ywp!\n",
"Shift 23 => Cd! D'h v xjjg xvo!\n",
"Shift 24 => Bc! C'g u wiif wun!\n",
"Shift 25 => Ab! B'f t vhhe vtm!\n"
]
}
},
"outputs": [],
"source": []
],
"source": [
"import os\n",
"\n",
"path = os.getcwd()\n",
"\n",
"def base64_decode(input_string):\n",
" BASE64_CHARS = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\"\n",
" decoded_string = bytearray()\n",
" value = 0\n",
" bits = -8\n",
"\n",
" for character in input_string:\n",
" if character not in BASE64_CHARS:\n",
" if character == \"=\":\n",
" break\n",
" continue\n",
" \n",
" value = (value << 6) + BASE64_CHARS.index(character)\n",
" bits += 6\n",
"\n",
" if bits >= 0:\n",
" decoded_string.append((value >> bits) & 0xFF)\n",
" bits -= 8\n",
" \n",
" return decoded_string.decode()\n",
"\n",
"def extract_message(data, offset):\n",
" # Extract the length of the Base64 message (first 32 bits)\n",
" length_bits = ''.join(str(data[offset + i] & 1) for i in range(32))\n",
" print(f\"Length bits: {length_bits}\")\n",
" base64_length = int(length_bits, 2)\n",
" print(f\"Extracted Base64 length (in characters): {base64_length}\")\n",
"\n",
" # Extract the Base64 message\n",
" binary_message = ''.join(str(data[offset + 32 + i] & 1) for i in range(base64_length * 8))\n",
" base64_message = ''.join(chr(int(binary_message[i:i+8], 2)) for i in range(0, len(binary_message), 8))\n",
" print(f\"Extracted Base64 message: {base64_message}\")\n",
" print(f\"Extracted Binary message: {binary_message}\")\n",
"\n",
" # Decode the Base64 message\n",
" return base64_decode(base64_message)\n",
"\n",
"def caesar_cipher_encode(input_string, shift):\n",
" encoded_string = \"\"\n",
" for character in input_string:\n",
" if character.isalpha():\n",
" base = ord('a') if character.islower() else ord('A')\n",
" encoded_string += chr((ord(character) - base + shift) % 26 + base)\n",
" else:\n",
" encoded_string += character # Non-alphabet characters remain unchanged\n",
" return encoded_string\n",
"\n",
"def caesar_cipher_decode(input_string, shift):\n",
" return caesar_cipher_encode(input_string, -shift) # Reverse the shift\n",
"\n",
"def caesar_cipher_brute_force(input_string):\n",
" print(\"Brute-forcing Caesar Cipher:\")\n",
" for shift in range(26):\n",
" print(f\"Shift {shift} => {caesar_cipher_decode(input_string, shift)}\")\n",
"\n",
"encoded_file_path = os.path.join(path, \"hiddencat.bmp\")\n",
"with open(encoded_file_path, \"rb\") as f:\n",
" data = f.read()\n",
"\n",
"# Specify the offset where the pixel data starts (e.g., 54 for standard BMP)\n",
"pixel_data_offset = int.from_bytes(data[10:14], byteorder='little')\n",
"\n",
"# Extract hidden message\n",
"hidden_message = extract_message(data, pixel_data_offset)\n",
"print(f\"Extracted message: {hidden_message}\")\n",
"\n",
"# Perform Caesar Cipher brute-forcing on the extracted message\n",
"caesar_cipher_brute_force(hidden_message)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Expected Output"
"From this we can see the one that makes the most sense is shift 18, with the results `Shift 18 => Hi! I'm a cool cat!`, showing the message was encoded with a shift of 18.\n",
"\n",
"```{admonition} Note\n",
":class: note\n",
"This will only work for simple ciphers like the Caesar Cipher. More complex encryption methods will require more sophisticated decryption techniques.\n",
"```"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "jupyter-books",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python"
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.7"
}
},
"nbformat": 4,
Expand Down
Loading

0 comments on commit 4b72580

Please sign in to comment.