I found the following XOR encryption function on the internet:
void xor_encrypt(char *key, char *string)
{
int i, string_length = strlen(string);
for
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.
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.
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.
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.