加密:按位反转和位移?

时间:2009-08-05 18:46:12

标签: encryption xor

我正在尝试撤消XOR加密。我有加密代码:

// 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);
}

第一行很好。

第二和第三不是。我的3个问题是:

  1. 我想我可以反转比特移位,它会正常工作吗?
  2. 但是如何反转按位&amp; ?那么#2如何逆转呢?
  3. 所以,如果对#1的答案是肯定的,我知道如何做#2,那么我可以这样做并且能够解密是吗?

4 个答案:

答案 0 :(得分:4)

您提供的代码似乎只是对每个4位半字节数据执行XOR(即,一次相当于一个十六进制字符)。

按位&和移位操作只是掩盖了在for循环的每一轮中使用的特定位集。你不需要“恢复”任何丢失的位,因为所有这些都是创建一个位掩码。

由于这是一个直接的XOR加密,它有以下解密程序:

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);
}

这恰好是加密例程(通过使用相同密钥通过加密例程运行密文来解密XOR加密)。

当然,我觉得有必要指出XOR加密只是一个玩具 - 这是一个令人难以置信的弱点,容易打破。所以我希望你只是在玩耍或学习。

不幸的是,这种代码在实际产品中经常会出现这种情况......

答案 1 :(得分:1)

你不能100%放心地改变它可以工作的位移。

0011&gt;&gt; 1变为0001

0001&lt;&lt; 1变为0010

倒转&amp;?再次......你试图从一个答案中提取两个输入值。 1001可以由(1111&amp; 1001)或(1011&amp; 1101)形成。有许多可能的组合。

我注意到位移可能不会受到我刚刚给出的问题的影响,因为它们首先被左移位,然后向右移位相同的数量。

答案 2 :(得分:0)

正如Michael所说,简单XOR“加密”的解密程序与加密程序相同。

但我可以在代码中看到问题。 0xF值是(带符号)整数常量,如果将它们移位的位数多于int,则结果是未定义的。

将它们更改为无符号长long常量(0xFULL) - 并将k更改为无符号long long,原因相同。

答案 3 :(得分:0)

感谢所有的答案,但是这整个xor加密算法最终只做了一件事,就是c = a ^ b。

因此,如果不更改代码中的任何内容,我只需使用带有加密字符串的密钥,我将获得解密后的值。

但是像迈克尔所说的那样,代码会根据十六进制字符进行加密。