【问题标题】:How to decrypt simple XOR encryption如何解密简单的异或加密
【发布时间】:2014-01-01 23:32:39
【问题描述】:

我在网上找到了以下异或加密功能:

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

效果很好,但我也想解密字符串。

例如:

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

所以基本上在我加密字符串之后,我会使用相同的加密密钥来解密之前加密的字符串。

我对编程很陌生,我只想知道如何解密以前加密的字符串。谢谢,感谢所有帮助。

【问题讨论】:

  • 解方程a = b ^ cb
  • 您的麻烦在于了解XOR encryption 的工作原理,而不是编程部分。

标签: c encryption xor


【解决方案1】:

XOR 加密的一个很酷的地方是,当你应用它两次时,你会得到原始字符串 - 请参阅 http://en.wikipedia.org/wiki/XOR_cipher

在您的函数 xor_decrypt 中,您获取字符串和密钥并返回字符串 ^ 密钥。如果,现在,你再次与键异或,你得到 (string ^ key) ^ key = string ^ (key ^ key) = string ^ identity = string (通过异或运算符的属性:http://en.wikipedia.org/wiki/Exclusive_or#Properties

因此,您可以在第一个 xor_encrypt 的输出上再次运行您的函数 xor_encrypt。

【讨论】:

  • 直到关键字符和对应的输入字符串字符相同...
  • @floris - a ^ a == 0 和 a ^ 0 == a,因此该语句仍然成立。 (再次运行该函数会返回原始字符串。)
  • @MarcelPopescu - 当加密字符串中包含 0 时,将被视为文件结尾(由上面编写的函数)并且解密将停止。这就是为什么我提倡(在我的回答中 - 在“警告 1:空字符”下)将原始字符串长度保留在变量中,而不是依赖 strlen,这在 keyChar == stringChar 时对编码字符串是错误的。我坚持我所说的。
【解决方案2】:

使用 XOR,解密与加密完全相同。通过xor_encrypt 方法再次运行相同密钥的加密字符串),您将获得纯文本。

警告 1:空字符

需要注意的一点:如果字符串中的字符与键中的相应字符匹配,则您的结果将是'\0'。这将被您当前的代码解释为“字符串结尾”,并会停止解密。为了避免这种情况,您需要将“实际”字符串的长度作为参数传递给您的函数。

警告 2:快捷键

您还需要确保不会超出密钥的末尾 - 如果纯文本很长,您可能需要重复密钥。您可以使用 % 运算符来执行此操作 - 只需从头开始回收密钥即可。

以下是展示这些技术的完整示例:

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

这(没有意识到 kay == 字符串的问题)会导致解密被截断(plain 中的 ikey 中的相同字母匹配):

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'

省略我上面标记的那行(即,保持n 的值作为字符串的原始长度),你的结果是

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'

完全符合您的预期。

【讨论】:

  • 在“加密”文本中值得注意的一点是:有一些“可打印”字符,特别是 A(第 5 位)、D(第 8 位)、B(第 14 位)。这些对应于原始文本中的空格,结果是键字符串的大写字母。这不是巧合,也是这种方法的真正弱点。特别是如果密钥很短,您可以快速将其拼凑在一起......应该严格用于娱乐,而不是实际加密。
猜你喜欢
  • 2015-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-31
  • 1970-01-01
  • 2014-06-28
  • 2017-12-20
相关资源
最近更新 更多