Help me with XOR encryption?

Pages: 12
Mar 23, 2011 at 7:20pm
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;    
}

Mar 23, 2011 at 8:25pm
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 ;)
Mar 24, 2011 at 6:29pm
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.
Mar 24, 2011 at 6:39pm
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 Mar 24, 2011 at 6:41pm
Mar 24, 2011 at 7:05pm
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.
Mar 24, 2011 at 7:09pm
Strings are (string.size()) * less efficient than calculating the key in the beginning...
Mar 29, 2011 at 5:54pm
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;    
}
Mar 29, 2011 at 6:42pm
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()]);
    }
    
}
Mar 30, 2011 at 4:31am
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.
Mar 30, 2011 at 4:13pm
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;    
}

Mar 30, 2011 at 4:41pm
Put this:
str((istreambuf_iterator<char>(in_stream)), istreambuf_iterator<char>());

after this

in_stream.open (filein.c_str()); //Open the file
Mar 30, 2011 at 6:21pm
oh duh xD but it's still doing it :(
Mar 30, 2011 at 6:28pm
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.
Mar 30, 2011 at 6:51pm
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"
Mar 30, 2011 at 6:57pm
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.
Mar 30, 2011 at 7:07pm
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;    
}
Mar 30, 2011 at 7:25pm
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 Mar 30, 2011 at 7:29pm
Mar 30, 2011 at 7:41pm
OMG YES!!!! it works at long last!!!
THANK YOU SO MUCH FOR YOUR HELP!!
Mar 30, 2011 at 7:55pm
No problem =) Glad I could help
Mar 30, 2011 at 8:38pm
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