0

我正在尝试反转 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. 但是我如何反转按位 & ?那么#2是如何反转的呢?
  3. 因此,如果#1 的答案是肯定的,并且我知道如何做#2,那么我可以这样做并且能够解密是吗?
4

4 回答 4

5

您提供的代码似乎只是对每个 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 加密只是一个玩具——它非常弱且容易破解。所以我希望你只是在玩耍或学习。

不幸的是,这种代码在实际产品中出现的频率很高……

于 2009-08-05T18:58:05.273 回答
1

您不能 100% 确信它会起作用来反转位移。

0011 >> 1 变成 0001

0001 << 1 变为 0010

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

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

于 2009-08-05T18:51:20.187 回答
0

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

因此,无需更改代码上的任何内容,我只需将密钥与加密字符串一起使用,我就会得到解密后的值。

但就像迈克尔说的那样,代码对每个十六进制字符进行加密。

于 2009-08-09T11:44:53.240 回答
0

正如迈克尔所说,简单异或“加密”的解密例程与加密例程相同。

不过,我可以在您的代码中看到一个问题。0xF 值是(有符号的)整数常量,如果您将它们移动的位数超过 int 的位数,则结果是未定义的。

将它们更改为 unsigned long long 常量 (0xFULL) - 并出于同样的原因将 k 更改为 unsigned long long。

于 2009-08-06T00:18:28.233 回答