Search code examples
c++encryptionxor

XOR encryption with c++


I've implemented a fairly simple method to encrypt and decrypt string to a file and then back. The methods im using look as following:

string encrypt(string msg, string key) {
    string tmp(key);
    while (key.size() < msg.size()) key += tmp;
    for (std::string::size_type i = 0; i < msg.size(); ++i) msg[i] ^= key[i];
    return msg;
}

string decrypt(string msg, string key) {
    return encrypt(msg, key);
}

However some of the keys I am using are not very useful. The string gets encrypted correctly and written to a file. But when i try to decrypt everything (loading the file into a string, decrypt it, write is back to another file) the new file is significant smaller and doesnt contain the entire information stored in it.

The keys I've tried so far are:

string crypt = "abc";                           //works kinda well
string crypt = "_H84M!-juJHFXGT01X1*G6a$gEv";   //doesnt work
string crypt = "H84MjuJHFXGT01X1G6agEv";        //doesnt work either

I am hoping you can help me and give me any advice on how to choose a usable key.

The code for the file handling:

ofstream temp;
temp.open("temp", ios::in | ios::trunc);
temp << encrypt(buffer, crypt);
temp.close();


ifstream in(file);
string content((std::istreambuf_iterator<char>(in))                (std::istreambuf_iterator<char>()));
ofstream plain;
plain.open(newfile, ios::in | ios::trunc);
plain << decrypt(content, crypt);
plain.close();

Solution

  • Okay, all of your answers and comments pointed me in the right direction, but didnt work directly in my program.

    First, I changed the encryption algorithm in the way Slava suggested. Second, I switched the file handling The new way gets the entire length of the encrypted file and forces each character via an array of char into a new string. I know this isnt pretty, but I am able keep the entire code in string type.

    So I came up with the following:

    ifstream in(file, ios::binary);
    in.seekg(0, ios::end);              // go to the end
    int length = in.tellg();            // report location (this is the length)
    in.seekg(0, ios::beg);              // go back to the beginning
    char* content = new char[length];   // allocate memory for a buffer of appropriate dimension
    in.read(content, length);           // read the whole file into the buffer
    string content2 = "";
    for (int i = 0; i < length; i++) con31 += con3[i];  //append to string character by character
    ofstream plain;
    plain.open(newfile, ios::in | ios::trunc);
    plain << decrypt(content2, crypt);
    plain.close();
    

    This works pretty well for me. I hope I havent build in some heavy mistakes.