C ++ Brute强制XOR密码

时间:2015-10-01 13:38:47

标签: c++ algorithm encryption brute-force

我已经实现了XOR加密算法,如下所示:

string XOR(string data, const char* key)
{
    string xorstring = data; //initialize new variable for our xordata
    for (int i = 0; i < xorstring.length(); i++) { //for loop for scrambling bits in the string
    xorstring[i] = data[i] ^ key[i]; //scrambling the string/descrambling it
    } 
    return xorstring;
}

哪个工作正常,例如:string ciphertext = XOR("test", "1234");将返回密文,在解密时:string plaintext = XOR(ciphertext, "1234");它将返回&#39; test&#39;。

所以,我想创建一个算法,通过暴力强制来破解xor密码,所以基本上尝试用每个可能的密钥组合来解密密文。

它(应该)像这样工作:

  • 从字母字符数组生成字符串
  • xor(解密)给定的带有给定字符串的密文以获得明文
  • 之后,xor(加密)生成的明文并在if语句中比较它是否与原始密文匹配
  • 如果匹配,则发现正确的密钥解密密文。

这很简单,但我发现自己在算法中苦苦挣扎:

const char Numbers[11] = "0123456789";
const char AlphabetUpper[27] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const char AlphabetLower[27] = "abcdefghijklmnopqrstuvwxyz";

string XOR(string data, const char* key)
{
   string xorstring = data; //initialize new variable for our xordata
   for (int i = 0; i < xorstring.length(); i++) { //for loop for scrambling   bits in the string
    xorstring[i] = data[i] ^ key[i]; //scrambling the string/descrambling it
   }
   return xorstring;
 }

 string cipher, plain; //store the ORIGINAL ciphertext and plaintext

 int main()
 {
    plain = "test"; //set the plaintext
    cipher = XOR(plain, "1234"); //encrypt it with the xor function

    cout << plain << endl;  //output
    cout << cipher << endl; //output

    cout << "press enter to start bruteforcing!" << endl;
    getchar();

    while (true) //loop for bruteforcing
    {
       static int stringlength = 1; //the keylength starts from 1 and then
       //expands to 2,3,4,5, etc...
       BruteForce(stringlength, cipher, ""); //call the brute force function
       stringlength++; //increment the keylength
    }
    return 0;
}

void BruteForce(int length, string ciphertext,  string tempKey)
{
    static int count = 0; // for counting how many times key was generated
    string decipher, recipher; //for storing new XORed strings.
    if (length == 0) 
    {
       //decrypt the given ciphertext with the random key
       decipher = XOR(ciphertext, tempKey.c_str());
       //encrypt it again with the same key for comparison
       recipher = XOR(decipher, tempKey.c_str());

       cout << deciphered << endl; //output

       //compare the two ciphertexts
       if (ciphertext == recipher)
       {
         //....
          cout << "Key found! It was: '" << tempKey << "'" << endl;
          cout << "it took " << count << " iterations to find the key!";
          getchar();
       }
      return;
   }
   count++;
   //generate the keys.
   for (int i = 0; i < 26; i++) {
       std::string appended = tempKey + AlphabetLower[i];
       BruteForce(length - 1, ciphertext, appended);
    }
    for (int i = 0; i < 26; i++) {
       std::string appended = tempKey + AlphabetUpper[i];
       BruteForce(length - 1, ciphertext, appended);
     }
    for (int i = 0; i < 10; i++) {
       std::string appended = tempKey + Numbers[i];
       BruteForce(length - 1, ciphertext, appended);
   }
}

由于未知原因,算法工作。

非常奇怪,理论上它应该有用。程序运行时,它表示每次执行bruteforce()函数时都会找到密钥。试一试你自己。 有人能指出我在这里做错了吗?感谢帮助。感谢。

2 个答案:

答案 0 :(得分:3)

这是XOR操作的属性:对于每个键,您会发现

message XOR key XOR key == message

因此,检查该密钥是否正确的方法确实会返回所有可能的密钥。

此外,假设您有加密邮件E。然后,对于任何可能的纯文本邮件M,您总会找到一个密钥K,以便

E = M xor K

(虽然这样的K可以包含任意char s,而不仅仅是字母等。)因此,如果您在char中允许任意K s,那么密码就会牢不可破甚至在理论上(参见one-time pad)。

如果您只允许K中的字母和数字,则不能从给定的加密邮件中接收每个纯文本邮件。但是,您需要更多信息,了解纯文本可以从错误的文本中检测“真实”消息(例如,知道纯文本只包含字母,或者它是有效的英文文本等),您需要在代码中检查这一点。无论如何,我想即使使用这种额外的启发式方法,你也会获得许多可能的纯文本。

答案 1 :(得分:3)

它不起作用,因为你的任务是不可能的。一次性填充(xor)具有称为perfect secrecy的属性,这意味着您的密文可以以相同的概率解密为任何纯文本。因此,不可能知道哪个纯文本是原始文本。

对于您的计划,(message XOR key) XOR key始终只是回传消息。