Skip to content

Instantly share code, notes, and snippets.

@LukeHuckman
Last active June 23, 2021 22:39
Show Gist options
  • Save LukeHuckman/b7d09dbc99fb4a9f0fd14776d578e613 to your computer and use it in GitHub Desktop.
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
#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