Help me with XOR encryption?

Pages: 12
I need to make a program that asks the user to input a file name, then a key, then an output file name. I need to use an XOR encryption that encrypts character by character (or by every 100, etc)

What I have so far; it runs and all, but when I encrypt, then decrypt, i dont get the same thing as the original file. What am I doing wrong?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <cstdlib>
#include <iostream>
#include <string>
#include <fstream>

using namespace std;

int main(int argc, char *argv[])
{

    ifstream in_stream;
    ofstream out_stream;
    string key;
    char filein[256], fileout[256], buff[100], cyph[100];
   

    cout << "Enter the name of the file\n";
    cin >> filein;
        in_stream.open (filein);
    
    cout << "Enter the encryption key\n";
    cin >> key;
    
    cout << "Enter the name of the outgoing file\n";
    cin >> fileout;
    out_stream.open (fileout);
    
    while(!in_stream.eof())
    {
     int L = key.length();
     in_stream>>buff;
     for(int i=0; i<sizeof(buff);i++)
             {
              cyph[i]=buff[i]^key[i%L];
              out_stream<<cyph[i];
             }
     }
     
     in_stream.close ();
     out_stream.close ();   
      
    system("PAUSE");
    return EXIT_SUCCESS;    
}

Well you are doing several things... interestingly

First> why in the world are you using char arrays? AND strings?

second>You do know that when you xor each char multiple times with the same char set, you're not doing yourself any good, it's exactly the same as xoring the chars together and then xoring each char with the result...

third>Read my article. You'll see why this form of encryption is completely useless.

What I'd do, if I were you, is stop using character arrays, and come up with a little better encryption algorith. Of course if it's an assignment, it doesn't matter =)

Once you do that, I'll bet you can get it working ;)
1) because im not entirely sure what im doing. At first i went with all stings, but came up with errors; google searches lead me to use some character arrays. Which would be better to use?

2) That confused me a bit, but yeah again im not entirely sure what im doing; my professor is a huge douche and he doesnt even bother teaching the info before assigning the project, so im very lost when it comes to the encryption part.

3) Yeah its an assignment, so i have to use xor...

Im gonna play around with it more later today and hopefully put up an updated version later today.
No xor is great, just having a repeating key is completely useless...

sorry if #2 confused you. I'll see if I can explain.

say we have this byte of data we want to encrypt
10111100

and we have a string we want to encrypt it with
01001100 01000111 01010000

so the way you're doing it
you would xor the first data with each of the keys
1
2
3
4
5
6
7
8
9
10
10111100^
01001100 
________
11110000^
01000111 
________
10110111^
01010000
________
11100111 (final encrypted data)



now if we xor the keys together we get
1
2
3
4
5
6
7
01001100^
01000111 
________
00001011^
01010000
________
01011011 (final key)



now if we xor the original data with the final key
1
2
3
4
5
10111100^
01011011
________
11100111 (compare to final encrypted data)
11100111 (final encrypted data)


they're equal.

Soo what I'm saying is rather than encrypting every single byte (string.size) times, just xor the string's individual characters together and encrypt each byte (1) time!!!


Last edited on
After you're done with this try making a decrypter knowing the length of the key.

I'd just stick to strings if I were you.
Strings are (string.size()) * less efficient than calculating the key in the beginning...
this is painfully stressful; this is what I have so far
i have a text which says "example"; when i run it thru the program with the key "hi" i get
1
2
	<
i––—–áX·èD·hihiPfTiPfTihihihihiXfTi`–Ji¥ñÑhiTihihi²ñÑZ$j‡hihihihihihiRuññ––—–‘ÄÑ+ÇѸ—Ji¼ý" 


I encrypt that again with the same key and get "example ՕKhle"
and when I try to encrypt something with multiple words or lines it gets even more fucked up.

Can someone point out where my errors are? and possibly what i need to do to fix them?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <cstdlib>
#include <iostream>
#include <string>
#include <fstream>


using namespace std;

int main(int argc, char *argv[])
{
    string filein, fileout, key;
    char buff[100], ciph[100];
    ifstream in_stream;
    ofstream out_stream;
    
    
    cout << "Enter the name of the file\n";
    cin >> filein;
    in_stream.open (filein.c_str(), ios:: in | ios::binary);
    
    cout << "Enter the encryption key\n";
    cin >> key;

    
    cout << "Enter the name of the outgoing file\n";
    cin >> fileout;
    out_stream.open (fileout.c_str(), ios::out | ios::binary);
    
    while(!in_stream.eof())
    {
     int L = key.size();
     in_stream.get(buff, 100);
     
     for(int i=0; i<sizeof(buff);i++)
             {ciph[i]=buff[i]^key[i%L];}
     out_stream<<ciph;
            
     }
     
     in_stream.close ();
     out_stream.close ();   
    
    system("PAUSE");
    return EXIT_SUCCESS;    
}
The problem... Again lies within the way you're using your char[], again I'm going to say use strings.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <string>
#include <fstream>


using namespace std;

int main()
{
    
    ifstream ifs("infile.txt");    
    
    string str((istreambuf_iterator<char>(ifs)), istreambuf_iterator<char>());
    
    //str now holds the contents of the entire file. found with google 
    //http://www.gamedev.net/topic/353162-reading-a-whole-file-into-a-string-with-ifstream/
    
    ofstream ofs("outfile.txt");
    
    string key = "key";
    
    for (int temp = 0; temp < str.size(); temp++){
        ofs << (str[temp] ^ key[temp % key.size()]);
    }
    
}
closed account (Lv0f92yv)
It might be worth noting that using this method will give an obvious indication of what (part by part) of the key is, especially when xoring against a space character. This might not be a problem for your assignment - but it is yet another product of the primitive scheme used here.

Good luck.
I figured as much, but strings seem to give me problems, I put the strings in there, but now my program wont end. it will ask for the users input on input file, key, and output file, then just stay there with nothing happening. (usually it would go to the "system pause" saying "press any key to continue."

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <cstdlib>
#include <iostream>
#include <string>
#include <fstream>
#include <cstring>


using namespace std;

int main(int argc, char *argv[])
{   
    ifstream in_stream;
    string filein, fileout, key, str((istreambuf_iterator<char>(in_stream)), istreambuf_iterator<char>());
    ofstream out_stream;
    int e;
    
    cout << "Enter the name of the file\n";  
    cin >> filein; //User inputs incoming file name
    in_stream.open (filein.c_str()); //Open the file
    
    cout << "Enter the encryption key\n";
    cin >> key; //User inputs the key

    
    cout << "Enter the name of the outgoing file\n";
    cin >> fileout; //User inputs the outgoing file name
    out_stream.open (fileout.c_str()); //Opens the file
    
    while(!in_stream.eof()) 
    {
     int L = key.size(); //Declaring the size of the key
    
     
     for(int i=0; i<str.size();i++) //Loop for the encryption
             {out_stream << (str[i] ^ key[i%L]);} //XOR encryption  
     }
     
     in_stream.close (); //close the incoming file
     out_stream.close ();   //close the outgoing file


    system("PAUSE");
    return EXIT_SUCCESS;    
}

Put this:
str((istreambuf_iterator<char>(in_stream)), istreambuf_iterator<char>());

after this

in_stream.open (filein.c_str()); //Open the file
oh duh xD but it's still doing it :(
1
2
3
4
5
6
7
8
while(!in_stream.eof()) 
    {
     int L = key.size(); //Declaring the size of the key
    
     
     for(int i=0; i<str.size();i++) //Loop for the encryption
             {out_stream << (str[i] ^ key[i%L]);} //XOR encryption  
     }


you never actually read anything in from in_stream here, it's an infinite loop. Get rid of the while loop.
oh i see, but i think im doing something wrong with the encryption
the main file says "example" encrypted with the key "hi" turns into "13179424513" encrypted again with "hi" turns into "8990899481939093938891"
It's possible, it's also possible that the reading in function is failing. When I do my binary file handling I always use vectors, but I'm just crazy...

Post your new code, And I'll actually look at it in my IDE. Right off the bat I can't see the problem.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <cstdlib>
#include <iostream>
#include <string>
#include <fstream>
#include <cstring>


using namespace std;

int main(int argc, char *argv[])
{   
    ifstream in_stream;
    string filein, fileout, key; 
    ofstream out_stream;
    int e;
    
    cout << "Enter the name of the file\n";  
    cin >> filein; //User inputs incoming file name
    in_stream.open (filein.c_str(), ios::in | ios::binary); //Open the file
    
    string str((istreambuf_iterator<char>(in_stream)), istreambuf_iterator<char>());
    
    cout << "Enter the encryption key\n";
    cin >> key; //User inputs the key

    
    cout << "Enter the name of the outgoing file\n";
    cin >> fileout; //User inputs the outgoing file name
    out_stream.open (fileout.c_str(), ios::out | ios::binary); //Opens the file
    
     int L = key.size(); //Declaring the size of the key
        
     for(int i=0; i<str.size();i++) //Loop for the encryption
             {out_stream << (str[i] ^ key[i%L]);} //XOR encryption  
     
     
     in_stream.close (); //close the incoming file
     out_stream.close ();   //close the outgoing file


    system("PAUSE");
    return EXIT_SUCCESS;    
}
You're outputting the int value of the chars, static cast to a char to get what you want.

change this

{out_stream << (str[i] ^ key[i%L]);}

to this

{out_stream << char(str[i] ^ key[i%L]);}


Now the problem lies in the way xor returns the value. When you xor 2 char's it returns the ascii value as a result. When we use char() <-[cstyle cast] we temporarily cast the result of what is returned to a char.
Last edited on
OMG YES!!!! it works at long last!!!
THANK YOU SO MUCH FOR YOUR HELP!!
No problem =) Glad I could help
closed account (zwA4jE8b)
just wondering..

why are you using the index i%L for the key subscript?

Does that make it loop through the key?
Pages: 12