Thread: XOR encrypt with variable key length

  1. #1
    Madly in anger with you
    Join Date
    Nov 2005
    Posts
    211

    XOR encrypt with variable key length

    hey all,
    I am trying to write a simple string encryptor using XOR based on some code posted here (I think Dave_Sinkula is a member here too): http://www.daniweb.com/code/snippet530.html

    here it is, my output from this program is looking like what would be caused by a buffer overrun (a bunch of garbage, note that it is not the XOR'ed string, it is longer than it).

    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main(int argc, char *argv[])
    {
    	unsigned char buf[100];
    	size_t count, i, j = 0;
    
    	count = strlen(argv[1]) + 1;
    
    	for(i = 0; i < count; i++) {
    		buf[i] ^= argv[2][j++];
    
    		if(argv[2][j] == '\0')
    			j = 0;
    	}
    
    	printf("%s", buf);
    
    	return 0;
    }
    argv[1] is obviously the string to encrypt, and argv[2] is the key to encrypt it with. I am trying to do this in a way that the key does not have to be the same length as the string (since thats inconvient when the string is user input).

    could anyone please tell me what looks wrong here and what I should do to fix it?


    thanks in advance!

    Intel Core 2 Quad Q6600 @ 2.40 GHz
    3072 MB PC2-5300 DDR2
    2 x 320 GB SATA (640 GB)
    NVIDIA GeForce 8400GS 256 MB PCI-E

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Store the length of the key in j. Use:
    Code:
    buf[i] ^= argv[2][ i %  j ];

    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by sl34k
    I am trying to do this in a way that the key does not have to be the same length as the string
    That's what this part is doing:
    Code:
    		if(argv[2][j] == '\0')
    			j = 0;
    As it said in the original:
    Code:
    j = 0; /* restart at the beginning of the key */
    Quote Originally Posted by sl34k
    could anyone please tell me what looks wrong here and what I should do to fix it?
    Don't try to use printf with the encoded "string", though, if you are overwriting the terminating null character.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  4. #4
    Jaguar
    Join Date
    Sep 2006
    Posts
    12
    intialize buf array.

    Jag

  5. #5
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by jaguar23
    intialize buf array.
    That too. Or otherwise use the input string that you are attempting to encrypt.
    Code:
    #include <stdio.h>
    
    int main(int argc, char *argv[])
    {
       if ( argc == 3 )
       {
          unsigned char buf[100];
          size_t i, j = 0;
          for ( i = 0; i < argv[1][i] != '\0'; i++ )
          {
             buf[i] = argv[1][i] ^ argv[2][j++];
             if ( argv[2][j] == '\0' )
             {
                j = 0;
             }
             printf("%02X", (unsigned)buf[i]);
          }
       }
       return 0;
    }
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  6. #6
    Madly in anger with you
    Join Date
    Nov 2005
    Posts
    211
    yeah I know thats what that part was doing (the key will simply be used again if the string to encrypt is longer than it). I also know I should be checking argc for the number of arguments, this was a simple test with XOR encryption, I plan on writing it as a function, this was just a test to see if it worked.

    overwriting the null is probably what is causing the overrun when I print the string.

    thanks Dave_Sinkula for the code you posted, that is more efficient than the way I was doing it with strlen.

    Intel Core 2 Quad Q6600 @ 2.40 GHz
    3072 MB PC2-5300 DDR2
    2 x 320 GB SATA (640 GB)
    NVIDIA GeForce 8400GS 256 MB PCI-E

  7. #7
    Madly in anger with you
    Join Date
    Nov 2005
    Posts
    211
    well I have another problem.

    I make the SLIGHTEST change to Dave_Sinkula's above code, and all of the sudden it stops working. it is now outputting strings of lengths nothing close to the length of the input string, in funny characters ontop of that (again, what looks like what is caused by an overrun, things like smiley face characters and such). the change is printing the crypted characters as characters opposed to their hex values:

    Code:
    #include <stdio.h>
    
    int main(int argc, char *argv[])
    {
    	unsigned char buf[260];
    	size_t i, j = 0;
    
    	if(argc == 3) {
    		for(i = 0; argv[1][i] != '\0'; i++) {
    			buf[i] = argv[1][i] ^ argv[2][j++];
    
    			if(argv[2][j] == '\0')
    				j = 0;
    
    			printf("%c", buf[i]);
    		}
    	}
    	else
    		printf("Usage: x0r <string> <key>\n\n");
    
    	return 0;
    }
    I'd like to write this in a way that I can encrypt the input string, and pass the crypted copy back into the program with the key it was crypted with to output the originally inputted string (basically decrypting it, I believe this is how XOR works). the hex conversion spoils this, as the output value will always be different than that that was originally encrypted with the key (I will have hex values outputted, and when I pass those hex values back into the program with the key, I will not get the originally inputted string, instead a copy of the hex values encrypted with the key, which is obviously not what I want).

    could anyone please tell me what the difference is between printing the hex value of a character and printing the actual character? I wouldn't think there would be any difference, but I am obviously wrong. perhaps it has something to do with the size of the crypted characters, some could be unicode (note that I am only passing normal characters like those from a-z for both the string and the key)?

    thanks in advance.
    Last edited by Bleech; 09-09-2006 at 12:18 AM.

    Intel Core 2 Quad Q6600 @ 2.40 GHz
    3072 MB PC2-5300 DDR2
    2 x 320 GB SATA (640 GB)
    NVIDIA GeForce 8400GS 256 MB PCI-E

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    Do you know what 'a' ^ 'a' evaluates to?
    Generally, the result isn't going to be another printable character, so using %c is just going to produce garbage strings.

    Take Dave's code and examine the output. Anything from 00 to 1F just isn't going to print out right with %c
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Madly in anger with you
    Join Date
    Nov 2005
    Posts
    211
    since I am encrypting the string, I would like to be able to decrypt it, but the hex conversion spoils this.

    for example:

    1. I input a string with a key to be encrypted.
    2. The encrypted string is outputted in hex values.
    3. I pass the hex values back into the program with the key.
    4. I get the output of the hex values encrypted with the key.

    as you see it is not working quite as I would like it to. is there any way around this? I am assuming there isn't, other than to write a seperate decrypt function. I was hoping to do this all with the same function, because of the nature of XOR, but its probably impossible.

    Intel Core 2 Quad Q6600 @ 2.40 GHz
    3072 MB PC2-5300 DDR2
    2 x 320 GB SATA (640 GB)
    NVIDIA GeForce 8400GS 256 MB PCI-E

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    But printing out in hex is something you're only doing for display purposes.

    If you do
    Code:
    n = strlen( message );
    printf( "%s\n", message );
    encrypt( buffer1, message, n, key );
    encrypt( buffer2, buffer1, n, key );
    printf( "%s\n", buffer2 );
    You should get back to where you started.

    Likewise if you choose to do
    - encrypt
    - printf using %x
    - scanf using %x (to undo the printing in hex)
    - encrypt
    You will again get back to where you started.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 16
    Last Post: 11-23-2007, 01:48 PM
  2. About aes
    By gumit in forum C Programming
    Replies: 13
    Last Post: 10-24-2006, 03:42 PM
  3. Window message loop (Keys)
    By Blackroot in forum Windows Programming
    Replies: 3
    Last Post: 09-12-2006, 05:15 PM
  4. Need help
    By awkeller in forum C Programming
    Replies: 2
    Last Post: 12-09-2001, 03:02 PM
  5. BST/Red and Black Tree
    By ghettoman in forum C++ Programming
    Replies: 0
    Last Post: 10-24-2001, 10:45 PM