Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

In a hacking competition, our team breaks into the adversary s computer and finds the following files. $ ls encrypt.c encrypted - message 2 encrypted

In a hacking competition, our team breaks into the adversarys computer and finds the following files.
$ ls
encrypt.c encrypted-message2 encrypted-message4 encrypted-message6
encrypted-message1 encrypted-message3 encrypted-message5 encrypted-message7
We cannot see the content of the seven encrypted files but we are able to see the content of file encrypt.c.
#include
#include
#include
#include
#include
#include
#define MAX 10240
//encrypt the message and write the result to file fd
void encrypt(char *message, unsigned char key, unsigned char shift, int fd)
{
int len = strlen(message);
printf("len =%d
", len);
int msg[len];
for(int i =0; i 0);
//note how we open the file
fd = open(argv[2], O_WRONLY | O_TRUNC | O_CREAT, 0600);
if(fd <0)
{
printf("Cannot open the file
");
return -1;
}
int key = atoi(argv[3]);
int shift = atoi(argv[4]);
assert(key >=0 && key <=255);
assert(shift >=0 && shift <=24);
encrypt(message, key, shift, fd);
//remember to close the file
close(fd);
return 0;
}
We believe these seven files are encrypted using the above code. Now we need to break the code: decrypt
the seven files to see their original content.
From the code we can see that each character in the original message is converted to an integer by applying
bit shifting (<<) and then an exclusive or (^) operation with a key. The number of shifts and the key are
not known, since they are passed as command line arguments. We will use a brute-force method to try all
combinations of shift and key values and see which combination reveals the original message.
To break the code, we use a dictionary to check the decrypted text. For example, we can count the number
of words in the decrypted text, according to the dictionary. We can even be more creative and come up with
better measures.
The content of the first few lines of the dictionary file dict.txt are the following.
aardvark
aardwolf
aaron
aback
abacus
abaft
abalone
abandon
abandoned
abandonment
abandons
abase
Note the dictionary file is sorted alphabetically. We can take advantage of this fact in our code.
2
Below is the main() function for our program.
//Do not change the main() function
int main(int argc, char *argv[])
{
if(argc !=2)
{
printf("%s encrypted-message
", argv[0]);
return 0;
}
read_file_to_array("dict.txt");
int encrypted[MAX];
int len = read_encrypted(argv[1], encrypted);
char message[MAX];
strcpy(message,"");
search(encrypted, len, message);
printf("%s
", message);
return 0;
}
The function search() is already implemented as following.
//search using all the (key, shift) combinations
//to find the original message
//result is saved in message
void search(const int *encrypted, int len, char *message)
{
char decrypted[MAX];
int max_score =0;
strcpy(message,"");
for(unsigned char k =0; k <255; k++)
{
for(unsigned char shift =0; shift <=24; shift++)
{
decryption(k, shift, encrypted, len, decrypted);
int score = message_score(decrypted);
if(score > max_score)
{
max_score = score;
strcpy(message, decrypted);
}
}
}
}
We need to implement the following functions.
//TODO
//Test wether a string word is in the dictionary
//Return 1 if word is in the dictionary
3
//Return 0 otherwise
//Be efficient in implementing this function
//Efficiency is needed to pass test cases in limited time
int in_dict(char *word)
{
}
//TODO
//Use key and shift to decrypt the encrypted message
//len is the length of the encrypted message
//Note the encrypted message is stored as an array of integers (not chars)
//The result is in decrypted
void decryption(unsigned char key, unsigned char shift, const int *encrypted, int len, char *dec
rypted)
{
}
//TODO
//calculate a score for a message msg
//the score is used to determine whether msg is the original message
int message_score(const char *msg)
{
}
//TODO
//read the encrypted message from the file to encrypted
//return number of bytes read
int read_encrypted(char *filename, int *encrypted)
{
}
starter code
#include
#include
#include
#include
#include
#include
#include
#define MAX 10240
#define MAX_WORD_COUNT 60000//we have less than 60000 words
#define MAX_WORD_LENGTH 80//each word is less than 80 letters
//Using these two global variables can be justified :)
char words[MAX_WORD_COUNT][MAX_WORD_LENGTH]; //2-d array to hold all the words
int word_count =0; //number of words, initilized to 0
//Note the words in the dictionary file are sorted
//This fact could be useful
void read_file_to_array(char *filename)
{
FILE *fp;
//open the file for reading
fp = fopen(filename,"r");
if(fp==NULL)
{
printf("Cannot open file %s.
", filename);
exit(-1);
}
//make sure when each word is saved in the array words,
//it does not ends with a '
'
//see how this is done using fscanf
while(!feof(fp))
fscanf(fp,"%s
", words[

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Database Fundamentals Study Guide

Authors: Dr. Sergio Pisano

1st Edition

B09K1WW84J, 979-8985115307

More Books

Students also viewed these Databases questions