views:

494

answers:

4

I'm trying to reverse an XOR encryption. I have the encryption code:

// Walk the 16 nibbles in the 64 bit long long, selecting the corresponding key digit
// and XORing it into the result.
unsigned long long result = 0;
for( i=0; i<16; i++ )
{
    int n = 4*(i % keyLen);
    int k = (key & (0xF << n)) >> n;
    result |= value&(0xF << 4*i) ^ (k<<4*i);
}

First line is fine.

Second and third is not. My 3 questions are:

  1. I guess I can just reverse the bitshift and it will work right?
  2. But how do I reverse a bitwise & ? So how does #2 is reversed?
  3. So if the answer is yes on #1, and I know how to do #2, then I can just do that and be able to decrypt yes?
+1  A: 

You can't reverse a bitshift with 100% confidence that it will work.

0011 >> 1 becomes 0001

0001 << 1 becomes 0010

And reversing an &? Again... you're trying to pull the two input values from a single answer. 1001 could be formed from (1111 & 1001) or (1011 & 1101). There are many possible combinations.

I have noticed that the bit shifts probably will not be affected by the problem I just gave because they are first bitshifted left and then right by the same amount.

sixfoottallrabbit
+4  A: 

The code you've presented seems to be just performing the XOR on each 4-bit nibble of data (ie. the equivalent of one hex charactrer at a time).

The bitwise & and shift operations are just masking off the particular set of bits to use in each round of the for loop. You don't need to 'recover' any lost bits, since all that's being done is creating a bitmask.

Since this is a straight-up XOR encryption, it has the following decryption routine:

unsigned long long result = 0;
for( i=0; i<16; i++ )
{  
    int n = 4*(i % keyLen);
    int k = (key & (0xF << n)) >> n;
    result |= value&(0xF << 4*i) ^ (k<<4*i);
}

Which happens to be the encryption routine (XOR encryption is decrypted by running the ciphertext through the encryption routine with the same key).

Of course, I feel obliged to point out that XOR encryption is just a toy - it's incredible weak and easy to break. So I hope you're just playing around or learning.

It's unfortunate how often this kind of code ends up in actual products though...

Michael Burr
Actually, if the key is completely random and is only ever used for encrypting one piece of data, XOR encryption is "One Time Pad"; which happens to be one of the few provably completely secure algorithms. Of course it is very impractical to only use a key once and once you reuse the key, it becomes - as you say - incredible weak.
Rasmus Faber
You're right, the one time pad is provably secure. But to be clear, it also requires that the key be as long as the data to be encrypted.
Michael Burr
A: 

As Michael says, the decryption routine for simple XOR "encryption" is the same as the encryption routine.

I can see a problem in your code, though. The 0xF values are (signed) integer constants, and if you shift those by more bits than an int has, the result is undefined.

Change them to unsigned long long constants (0xFULL) - and change k to unsigned long long for the same reason.

caf
A: 

hey guys,

thanks for all the answers, but this whole xor encryption algorithm just do one thing in the end, that is, c = a ^ b.

So without changing anything on the code, i simply use the key with the encrypted string and i will get the decrypted value back.

But like Michael said, the code does encryption per hex character.

David