This repository has been archived on 2025-04-11. You can view files and clone it, but cannot push or open issues or pull requests.
csce465pine64backup/hw3/task4/find_key.cpp

152 lines
4 KiB
C++
Raw Normal View History

2018-03-05 18:47:59 -06:00
#include <cstdio>
#include <iostream>
#include <fstream>
2018-03-05 23:05:46 -06:00
#include <sstream>
2018-03-05 18:47:59 -06:00
#include <cstring>
#include <ctype.h>
#include <openssl/evp.h>
using namespace std;
2018-03-05 23:05:46 -06:00
// This is the same as what was given, just added the key string as a parameter
// so I could manipulate it in here instead.
2018-03-05 18:47:59 -06:00
int do_crypt(FILE *in, FILE *out, string inkey, int do_encrypt)
{
/* Allow enough space in output buffer for additional block */
unsigned char inbuf[1024], outbuf[1024 + EVP_MAX_BLOCK_LENGTH];
int inlen, outlen;
EVP_CIPHER_CTX *ctx;
/*
* Bogus key and IV: we'd normally set these from
* another source.
*/
2018-03-05 23:05:46 -06:00
// hardcoding the IV because we already know what it is.
2018-03-05 18:47:59 -06:00
unsigned char iv[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
2018-03-05 23:05:46 -06:00
// I'm adding the spaces in here.
for(int i = inkey.length(); i < 16; ++i)
2018-03-05 18:47:59 -06:00
{
2018-03-05 23:05:46 -06:00
inkey += ' ';
2018-03-05 18:47:59 -06:00
}
2018-03-05 23:05:46 -06:00
// Converting the input key into an unsigned char array.
unsigned char key[17];
strcpy((char*) key, inkey.c_str());
2018-03-05 18:47:59 -06:00
/* Don't set key or IV right away; we want to check lengths */
ctx = EVP_CIPHER_CTX_new();
EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, NULL, NULL, do_encrypt);
OPENSSL_assert(EVP_CIPHER_CTX_key_length(ctx) == 16);
OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) == 16);
/* Now we can set key and IV */
EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, do_encrypt);
for (;;) {
2018-03-05 23:05:46 -06:00
inlen = fread(inbuf, 1, 1024, in);
2018-03-05 18:47:59 -06:00
if (inlen <= 0)
break;
if (!EVP_CipherUpdate(ctx, outbuf, &outlen, inbuf, inlen)) {
/* Error */
EVP_CIPHER_CTX_free(ctx);
return 0;
}
fwrite(outbuf, 1, outlen, out);
}
if (!EVP_CipherFinal_ex(ctx, outbuf, &outlen)) {
/* Error */
EVP_CIPHER_CTX_free(ctx);
2018-03-05 23:05:46 -06:00
// I added this just in case to make sure thigns cleaned up properly.
EVP_CIPHER_CTX_cleanup(ctx);
2018-03-05 18:47:59 -06:00
return 0;
}
fwrite(outbuf, 1, outlen, out);
EVP_CIPHER_CTX_free(ctx);
2018-03-05 23:05:46 -06:00
EVP_CIPHER_CTX_cleanup(ctx);
2018-03-05 18:47:59 -06:00
return 1;
}
int main()
{
2018-03-05 23:05:46 -06:00
// Initialize files.
2018-03-05 18:47:59 -06:00
FILE *input;
FILE *output;
2018-03-05 23:05:46 -06:00
// Open the needed files.
2018-03-05 18:47:59 -06:00
input = fopen("ciphertext.txt", "rb");
2018-03-05 23:08:19 -06:00
output = fopen("output.txt", "wb");
2018-03-05 18:47:59 -06:00
2018-03-05 23:05:46 -06:00
// I prefer ifstreams when dealing with files,
// but I leave the other two as file pointers
// so I don't have to change more code.
2018-03-05 18:47:59 -06:00
ifstream words("words.txt");
ifstream original("plaintext.txt");
2018-03-05 23:05:46 -06:00
// Just an initial key. It will be overwritten.
2018-03-05 18:47:59 -06:00
string key = "0123456789abcdef";
2018-03-05 23:05:46 -06:00
// Variable to storing the goal string.
2018-03-05 18:47:59 -06:00
string secret = "";
getline(original, secret);
2018-03-05 23:05:46 -06:00
// Variable for storing output when we read
// from the file that we wrote to.
string templine = "";
2018-03-05 18:47:59 -06:00
while(!words.eof())
{
2018-03-05 23:05:46 -06:00
// Get the current key to test with.
2018-03-05 18:47:59 -06:00
key = "";
getline(words, key);
2018-03-05 23:05:46 -06:00
// Only test it if it's less that 16 characters.
2018-03-05 18:47:59 -06:00
if(key.length() > 16)
{
continue;
}
2018-03-05 23:05:46 -06:00
// Try to decrypt with this key.
2018-03-05 18:47:59 -06:00
do_crypt(input, output, key, 0);
2018-03-05 23:05:46 -06:00
// Set the file pointers back to the beginning
// of the files.
rewind(input);
rewind(output);
// Read the file and see if it matches the original
// message, if it does, then we guessed the key.
2018-03-05 18:47:59 -06:00
fclose(output);
2018-03-05 23:05:46 -06:00
2018-03-05 23:08:19 -06:00
ifstream tempoutput("output.txt");
2018-03-05 23:05:46 -06:00
getline(tempoutput, templine);
tempoutput.close();
if(templine.compare("This is a top secret.") == 0)
{
// Output the key and the output text
// to prove we know the key and we
// successfully decrypted the message.
cout << key << endl;
cout << templine << endl;
break;
}
else
2018-03-05 18:47:59 -06:00
{
2018-03-05 23:05:46 -06:00
// We didn't decrypt it, try again,
// overwrite whatever was in the file.
2018-03-05 23:08:19 -06:00
output = fopen("output.txt", "wb");
2018-03-05 18:47:59 -06:00
}
}
fclose(input);
words.close();
original.close();
return 0;
}