Frage

I found the following XOR encryption function on the internet:

void xor_encrypt(char *key, char *string)
{
    int i, string_length = strlen(string);
    for(i=0; i<string_length; i++)
    {
        string[i]=string[i]^key[i];
        printf("%i", string[i]);
    }
}

It works perfect, but I would like to decrypt the string also.

For example:

void xor_decrypt(char *key, char *encrypted_string)
{
    //decrypt method goes here
}

So basically after I encrypt the string, I would use the same encryption key to decrypt the previously encrypted string.

I'm pretty new to programming and I would just like to know how to decrypt the previously encrypted string. Thanks, all help is appreciated.

War es hilfreich?

Lösung

One of the cool things about XOR encryption is that when you apply it twice, you get back the original string – see http://en.wikipedia.org/wiki/XOR_cipher.

In your function, xor_decrypt, you take string and key and return string ^ key. If, now, you xor that with the key again, you get (string ^ key) ^ key = string ^ (key ^ key) = string ^ identity = string (by properties of XOR operator: http://en.wikipedia.org/wiki/Exclusive_or#Properties)

Thus, you can just run your function, xor_encrypt, a second time on the output of the first xor_encrypt.

Andere Tipps

With XOR, decrypting is exactly the same operation as encrypting. Run the encrypted string through the xor_encrypt method again same key) and you have the plain text back.

warning 1: null characters

One thing to watch out for: if the character in the string matches the corresponding character in the key, your result will be '\0'. This will be interpreted by your current code as the "end of string" and would stop the decryption short. To circumvent this, you want to pass the length of the "actual" string as a parameter to your function.

warning 2: short keys

You also want to make sure you don't run past the end of your key - if the plain text is very long you might have to repeat the key. You can do this with the % operator - just recycle the key from the beginning.

Here is a complete example that shows these techniques:

#include <stdio.h>
#include <string.h>

void xor_encrypt(char *key, char *string, int n)
{
    int i;
    int keyLength = strlen(key);
    for( i = 0 ; i < n ; i++ )
    {
        string[i]=string[i]^key[i%keyLength];
    }
}

int main(void) {
  char plain[] = "This is plain text";
  char key[] = "Abcdabcdabciabcdabcd";
  int n = strlen(plain);
  // encrypt:
  xor_encrypt(key, plain, n);
  printf("encrypted string: \n");
  for(int ii = 0; ii < n; ii++) {
    if(plain[ii] > 0x32 && plain[ii] < 0x7F ) printf("%c", plain[ii]);
   else printf(" 0x%02x ", plain[ii]);
  }
  printf("\n");
  // **** if you include this next line, things go wrong!
  n = strlen(plain);
  xor_encrypt(key, plain, n);
  printf("after round trip, plain string is '%s'\n", plain);
}

This (not realizing the problem with kay == string) results in truncated decryption (the i in plain matches the same letter in key):

encrypted string: 
 0x15  0x0a  0x0a  0x17 A 0x0b  0x10 D 0x11  0x0e  0x02  0x00  0x0f B 0x17  0x01  0x19  0x16 
after round trip, plain string is 'This is pla'

Leaving out the line I marked above (i.e., keeping the value of n as the original length of the string), your result is

encrypted string: 
 0x15  0x0a  0x0a  0x17 A 0x0b  0x10 D 0x11  0x0e  0x02  0x00  0x0f B 0x17  0x01  0x19  0x16 
after round trip, plain string is 'This is plain text'

exactly as you would expect.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top