如何解密简单的XOR加密

时间:2013-12-14 03:29:13

标签: c encryption xor

我在互联网上找到了以下XOR加密功能:

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
}

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

我对编程很新,我只想知道如何解密以前加密的字符串。谢谢,所有的帮助表示赞赏。

2 个答案:

答案 0 :(得分:12)

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

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

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

答案 1 :(得分:11)

使用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 == string的问题)会导致截断解密(i中的plainkey中的相同字母匹配):

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'
完全按照你的预期完成。