Last active
June 23, 2021 22:39
-
-
Save LukeHuckman/b7d09dbc99fb4a9f0fd14776d578e613 to your computer and use it in GitHub Desktop.
Computer Penetration Tutorial: Deciphering multiple plaintexts encryped with the same key and finding the key
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdbool.h> | |
#define NO_OF_WORDS 24 | |
#define LENGTH 6 | |
int main() { | |
unsigned char ctxt[NO_OF_WORDS][LENGTH] = { // Ciphertext | |
{0xd1, 0x0d, 0x01, 0x90, 0xaa, 0x80}, | |
{0xd9, 0x11, 0x11, 0x87, 0xb6, 0x9b}, | |
{0xc2, 0x0a, 0x02, 0x9a, 0xb2, 0x8a}, | |
{0xd0, 0x0a, 0x02, 0x9a, 0xbb, 0x9d}, | |
{0xc8, 0x16, 0x1f, 0x9a, 0xbf, 0x88}, | |
{0xc1, 0x16, 0x02, 0x9a, 0xb2, 0x8a}, | |
{0xda, 0x16, 0x12, 0x81, 0xbd, 0x84}, | |
{0xd8, 0x10, 0x13, 0x89, 0xb0, 0x88}, | |
{0xd3, 0x1d, 0x17, 0x81, 0xac, 0x8b}, | |
{0xcb, 0x1e, 0x1b, 0x88, 0xaa, 0x9c}, | |
{0xc5, 0x1e, 0x1e, 0x86, 0xb2, 0x8a}, | |
{0xd6, 0x1e, 0x1d, 0x8d, 0xb1, 0x81}, | |
{0xd1, 0x1e, 0x1b, 0x94, 0xab, 0x9c}, | |
{0xc4, 0x1e, 0x1b, 0x95, 0xab, 0x82}, | |
{0xd3, 0x1c, 0x1b, 0x85, 0xae, 0x9b}, | |
{0xd4, 0x10, 0x14, 0x8c, 0xb1, 0x98}, | |
{0xd6, 0x10, 0x0d, 0x82, 0xb2, 0x8a}, | |
{0xcb, 0x1a, 0x14, 0x8c, 0xb1, 0x98}, | |
{0xd0, 0x1a, 0x0c, 0x94, 0xbb, 0x9d}, | |
{0xd3, 0x1c, 0x1b, 0x85, 0xad, 0x9c}, | |
{0xd7, 0x11, 0x1c, 0x89, 0xb0, 0x88}, | |
{0xc4, 0x16, 0x0b, 0x95, 0xbf, 0x83}, | |
{0xd1, 0x1e, 0x16, 0x83, 0xbb, 0x9d}, | |
{0xd3, 0x1c, 0x0c, 0x89, 0xa8, 0x8a}, | |
}; | |
unsigned char ptxt[NO_OF_WORDS][LENGTH]; // Plaintext | |
unsigned char key[LENGTH]; | |
// Guessing algorithm | |
for(int i = 0; i < LENGTH; i++) { // Character iteration | |
unsigned char xorval[NO_OF_WORDS]; | |
for(int j = 0; j < NO_OF_WORDS; j++) { // XOR value calculation | |
xorval[j] = ctxt[0][i] ^ ctxt[j][i]; | |
} | |
bool ptxtfound = false; | |
int notyet = 0; | |
for(unsigned char j = 0x61; j <= 0x7a; j++) { | |
for(int k = 0; k < NO_OF_WORDS; k++){ // Word iteration | |
if((j ^ xorval[k]) >= 0x61 && (j ^ xorval[k]) <= 0x7a) { // Guess and check | |
ptxt[k][i] = (j ^ xorval[k]); | |
if(k==NO_OF_WORDS-1){ | |
if(i > 3 && notyet < i) { | |
/* | |
* Special case for the fifth and sixth character: | |
* The correct guess is not the first guess and | |
* coincidentally is the same number of guesses | |
* as the character's position in the word. | |
*/ | |
notyet++; | |
break; | |
} | |
else { | |
ptxtfound = true; | |
break; | |
} | |
} | |
} | |
else { | |
break; // Use next letter if not in range | |
} | |
} | |
if(i!=0 && notyet == i || ptxtfound) | |
break; | |
} | |
} | |
// Finding the key (Brute force method) | |
for (int i = 0; i < LENGTH; i++) { | |
for (unsigned char j = 0x00; j < 0xff; j++){ | |
for (int k=0; k < NO_OF_WORDS; k++) { | |
if((ptxt[k][i] ^ j) == ctxt[k][i]){ | |
key[i] = j; | |
} | |
else { | |
break; | |
} | |
} | |
} | |
} | |
//Output | |
printf("\nCiphertext:\n"); | |
for (int i=0; i < NO_OF_WORDS; i++) { | |
for (int j = 0; j < LENGTH; j++) { | |
printf("%02x ", ctxt[i][j]); | |
} | |
printf("\n"); | |
} | |
printf("\nPlaintext:\n"); | |
for (int i = 0; i < NO_OF_WORDS; i++) { | |
for (int j = 0; j < LENGTH; j++) { | |
printf("%02x ", ptxt[i][j]); | |
} | |
printf("( "); | |
for (int j=0; j < LENGTH; j++) { | |
printf("%c ", ptxt[i][j]); | |
} | |
printf(")\n"); | |
} | |
printf("\nKey: "); | |
for (int i = 0; i < LENGTH; i++) | |
printf("%02x ", key[i]); | |
printf("\n"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment