解密用rand()加密的tex文件

时间:2018-03-27 16:35:23

标签: c++ random cryptography

Question I'm trying to solve

我想采取的方法是强制所有可能的密钥(种子),直到找到正确的密钥。我知道tex文件中的第一个字符,所以这些是我正在测试的。当我找到正确的序列时,我会停止程序并输出密钥。

/* The ISO/IEC 9899:1990 edition of the C standard */

#include <stdio.h>
#include <time.h>
#include <iostream>

//#define RAND_MAX 32767
static unsigned long int next = 1;
int rand(void) // RAND_MAX assumed to be 32767
{
    next = next * 1103515245 + 12345;
    return (unsigned int)(next/65536) % 32768;
}
void srand(unsigned int seed)
{
    next = seed;
}

using namespace std;

//Return a byte at a time of the rand() keystream
 char randchar() { 
  static int key;
  static int i = 0;

  i = i % 4;
  if (i == 0) key = rand();
  return ((char *)(&key))[i++];
}

int main(int argc, const char* argv[]) {


  for (unsigned int i = time(NULL); i >= 0; i--) //Try all possible return values of time(NULL) since today
  {

      srand(i); 

      cout << "Trying with time(NULL) = " << i << endl;

      FILE *input, *output;
      input = fopen("Homework1b-Windows.tex.enc", "r");
      output = fopen("Homework1b.tex", "w");

      int c,rc, test;
      int pos;
      pos = 0;
      bool pos0, pos1, pos2, pos3, pos4, pos5;
      pos0 = pos1 = pos2 = pos3 = pos4 = pos5 = false;
      char temp1, temp2;

      while ((c = fgetc(input)) != EOF) {
        rc=randchar();
        fputc(c^rc,output);

        test = c^rc;

        temp1 = (char)test;


        temp2 = '\\';

        if ((pos == 0) && (temp1 == temp2))
        {
                 pos0 = true;
        } 

        temp2 = 'd';

        if ((pos == 1) && (temp1 == temp2))
        {
                 pos1 = true;
        }

        /*

        temp2 = 'o';

        if ((pos == 2) && (temp1 == temp2))
        {
                 pos2 = true;
        }

        temp2 = 'c';

        if ((pos == 3) && (temp1 == temp2))
        {
                 pos3 = true;
        }

        */

        temp2 = 'u';

        if ((pos == 4) && (temp1 == temp2))
        {
                 pos4 = true;
        }

        temp2 = 'm';
        if ((pos == 5) && (temp1 == temp2))
        {
                 pos5 = true;
        }

        pos++;

      }
      fclose(input);
      fclose(output);

      if (pos0 && pos1 && pos4 && pos5)
      {
         cout << endl << "Cracked. The seed is time(NULL) = " << i << endl;
         break;
      }
  }

  system("pause");


}

我知道解密的tex文件以“\ document”开头。

我面临的问题是代码永远不会终止。它永远找不到正确的密钥(种子)。

任何帮助?

谢谢。

1 个答案:

答案 0 :(得分:2)

你的想法是合理的(蛮力从“现在”回来并寻找匹配的纯文本),但你的实现可以改进。 例如,您不应该打开和关闭循环内的文件。

如果您查看<template lang="pug"> el-dialog( width="600px", title="Users", :visible.sync="dialogVisible") el-form.demo-ruleForm(:model="editedItem", status-icon, :rules="formRules", ref="userForm", label-width="140px") el-form-item(label="Name", prop="firstName") el-input(v-model="editedItem.name", auto-complete="off") template(v-if="!changePassword") el-form-item el-button(@click="changePassword = true") Change Password? template(v-else) el-form-item(label="Password", prop="password") el-input(type="password", v-model="editedItem.password", auto-complete="off") el-form-item(label="Confirm Password", prop="confirmPassword") el-input(type="password", v-model="editedItem.confirmPassword", auto-complete="off") .dialog-footer(slot="footer") el-button(type="primary", @click="submitForm('userForm')") Save </template> <script> export default { name: 'dialog-add-edit-user', props: { editedItem: Object, }, data () { const validatePass = (rule, value, callback) => { if (value === '') { callback(new Error('Please input the password')) } else { if (this.confirmPassword !== '') { this.$refs.userForm.validateField('confirmPassword') } callback() } } const validatePass2 = (rule, value, callback) => { if (value === '') { callback(new Error('Please input the password again')) } else if (value !== this.editedItem.password) { callback(new Error('Two inputs don\'t match!')) } else { callback() } } return { formRules: { password: [ { validator: validatePass, trigger: 'blur' } ], confirmPassword: [ { validator: validatePass2, trigger: 'blur' } ] }, dialogVisible: false, changePassword: false, editedItem: { name: '', password: '', confirmPassword: '' } } }, methods: { submitForm (formName) { this.$refs[formName].validate((valid) => { if (valid) { this.$emit('save-item') console.log('submit!') } else { console.log('error submit!!') return false } }) } } } </script> 的实施方式,直接调用randchar()可能会更有效,并且一次比较四个字符。

实际上,您可以计算一次加密和纯文本的rand(),并简单地将xor返回的值与其进行比较。

为了加快速度,您可以直接在源文件中编写加密和纯文本的前8个字符,使用一个简单的函数将四个rand()打包到char

int

int to_int(const char buffer[4]) { return (static_cast<int>(buffer[0])) + (static_cast<int>(buffer[1]) << 8) + (static_cast<int>(buffer[2]) << 16) + (static_cast<int>(buffer[3]) << 24); }

main()

现在剩下的就是循环遍历所有可能的键并寻找匹配(并且正如@Raxvan指出的那样,你不应该检查 const int crypt1 = to_int("\x57\x12\x6f\x63"); const int crypt2 = to_int("\x51\x59\x65\x6e"); const int plain1 = to_int("\\doc"); const int plain2 = to_int("umen"); const int target1 = plain1 ^ crypt1; const int target2 = plain2 ^ crypt2; 或者循环永远不会完成):

key >= 0