首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >一种用Java编写的破解异或密码的进化算法

一种用Java编写的破解异或密码的进化算法
EN

Code Review用户
提问于 2022-09-29 01:46:10
回答 1查看 110关注 0票数 2

好的。因此,TryHackme是一个尝试在实验室用手教黑客的网站。他们有一个名为JVM逆向工程的房间,用户可以在这里反向工程Java应用程序,特别是我要求您查看的代码是用于任务5的。

任务5要求用户破解使用简单异或密码加密的密码。您可以自己逆向设计应用程序,但以下是重要的部分:

首先,它们的xor密码被定义为以下String

代码语言:javascript
复制
// Decompiled from the task #5 challenge.
private static String xor(String var0) {
  char[] var1 = var0.toCharArray();
  char[] var2 = new char[var1.length];

  for(int var3 = 0; var3 < var2.length; ++var3) {
     char var4 = var1[var3];
     var2[var3] = (char)(var4 ^ var3 % 3);
  }

  return new String(var2);
}

其次,如果输入密码的XOR等于xorcorrectPassword (即等于aRa2lPT6A6gIqm4RE的字符串),则密码是正确的。

我的解决方案是使用我自己修改和应用的道金斯黄鼠狼版本来“进化”,因为没有一个更好的术语,一个解决方案的“密码”可能是什么。在查看我的代码时,我希望能得到更好的反馈。以下是你在反馈中要考虑的一些问题:

  1. 我能采用更好的编码方式吗?
  2. 我可以在不影响代码易读性的情况下使代码更小吗?
  3. 我能优化我的代码使其运行更快吗?

以下是我的代码:

代码语言:javascript
复制
/*
 * An application to crack an XOR cipher using Dawkins' weasel
 * By A. S. "Aleksey" Ahmann <hackermaneia@riseup.net>
 * - Githubs: https://github.com/Alekseyyy
 * - TryHackMe: https://tryhackme.com/p/EntropyThot
 *
 * Note that some parts of this programme are borrowed from o-
 * -ther sources. Most notably, the "xor" function that retur-
 * -ns a String is the result of decompiling the .class file
 * of TryHackMe's problem. P1's random string generator is ba-
 * -sed off of the following website:
 * - https://www.baeldung.com/java-random-string
 */

import java.io.*;
import java.util.*;

public class Dawkins {
   private static final String correctPassword = "aRa2lPT6A6gIqm4RE";

   public static void main(String[] args) {
      Random random = new Random();
      int counter = 1;
    
      char[] target = correctPassword.toCharArray();
      char[] solution = new char[target.length];

      System.out.println("==========================================================");
      System.out.println("= A crude, amateurish implementation of Dawkins'          ");
      System.out.println("= weasel to crack the TryHackMe XOR cipher                ");
      System.out.println("= By A. S. \"Aleksey\" Ahmann <hackermaneia@riseup.net>   ");
      System.out.println("= - https://github.com/Alekseyyy                          ");
      System.out.println("= - https://tryhackme.com/p/EntropyThot                   ");
      System.out.println("==========================================================\n");

      boolean done = false;
      while (!done) {
         // [P1] Generate random string (of course the length of random string should = correctPassword)
         // - this "seed" is based off of the following: https://www.baeldung.com/java-random-string
         char[] seed = random.ints(48, 123)
            .filter(k -> (k <= 57 || k >= 65) && (k <= 90 || k >= 97))
            .limit(target.length)
            .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
            .toString().toCharArray(); 
         // [P2] Put the random string through the xor cipher, and split it into char array of course
         char[] nextGen = xor(new String(seed)).toCharArray();
         // [P3] Save the matching characters as "offspring"
         boolean emptySlots = false;
         for (int k = 0; k < solution.length; k++) {
            if (solution[k] != Character.MIN_VALUE) {
               continue;
            }
            else {
               emptySlots = true;
               if (nextGen[k] == target[k]) {
                  solution[k] = seed[k];
               }
            }
         }

         System.out.printf("Generation %d: %s\n", counter, new String(solution));
         counter++;
         if (!emptySlots) {
            done = true;
         }
      }

      System.out.printf("Solution: %s\n", new String(solution));
   }

   // From the decompile dump of "BasicStringObfuscation.class"
   private static String xor(String var0) {
      char[] var1 = var0.toCharArray();
      char[] var2 = new char[var1.length];

      for(int var3 = 0; var3 < var2.length; ++var3) {
         char var4 = var1[var3];
         var2[var3] = (char)(var4 ^ var3 % 3);
      }

      return new String(var2);
   }
}
```
代码语言:javascript
复制
EN

回答 1

Code Review用户

回答已采纳

发布于 2022-10-06 16:01:35

免责声明:我不是Java专家,我可能忽略了代码的一些要点。

最后迭代

当迭代solution的字符以检查它是否有效时,我们依赖于它以前的值,而不是我们可能给它的值。

因此,即使我们可以直接停止,我们也会经历一次额外的迭代。

这是我的建议

代码语言:javascript
复制
         // [P3] Save the matching characters as "offspring"
         boolean solutionIsValid = true;
         for (int i = 0; i < solution.length; i++) {
            if (solution[i] == Character.MIN_VALUE) {
               if (cipheredSeed[i] == target[i]) {
                  solution[i] = seed[i];
               } else {
                  solutionIsValid = false;
               }
            }
         }

我抓住这个机会:

  • 摆脱继续
  • 重命名几件事

原理

大量时间用于生成随机值,对它们进行加密并检查加密值,但大多数字符被加密、错误和/或未使用。

因为每个字符都是独立加密的(否则,这里的整个逻辑都会失败),逐字符前进可能会更快。

这提供了如下内容:

代码语言:javascript
复制
/*
 * An application to crack an XOR cipher using Dawkins' weasel
 * By A. S. "Aleksey" Ahmann <hackermaneia@riseup.net>
 * - Githubs: https://github.com/Alekseyyy
 * - TryHackMe: https://tryhackme.com/p/EntropyThot
 *
 * Note that some parts of this programme are borrowed from o-
 * -ther sources. Most notably, the "xor_str" function that retur-
 * -ns a String is the result of decompiling the .class file
 * of TryHackMe's problem. P1's random string generator is ba-
 * -sed off of the following website:
 * - https://www.baeldung.com/java-random-string
 */

import java.io.*;
import java.util.*;

public class Dawkins {
   private static final String correctPassword = "aRa2lPT6A6gIqm4RE";

   public static void main(String[] args) {
      char[] target = correctPassword.toCharArray();
      char[] solution = new char[target.length];

      System.out.println("==========================================================");
      System.out.println("= A crude, amateurish implementation of Dawkins'          ");
      System.out.println("= weasel to crack the TryHackMe XOR cipher                ");
      System.out.println("= By A. S. \"Aleksey\" Ahmann <hackermaneia@riseup.net>   ");
      System.out.println("= - https://github.com/Alekseyyy                          ");
      System.out.println("= - https://tryhackme.com/p/EntropyThot                   ");
      System.out.println("==========================================================\n");

      for (int i = 0; i < solution.length; i++) {
         // Loop over candidates
         for (char c = 48; c <= 123; c++) {
             if ((c <= 57 || c >= 65) && (c <= 90 || c >= 97)) {
                 // Check if valid
                 if (xor_c(c, i) == target[i]) {
                     solution[i] = c;
                 }
             }
         }
      }

      // TODO: Handle cases when 0 or many characters are found
      System.out.printf("Solution: %s\n", new String(solution));
   }

   // From the decompile dump of "BasicStringObfuscation.class" and then refactored
   private static char xor_c(char c, int index) {
       return (char)(c ^ index % 3);
   }
   private static String xor_str(String s) {
       char[] input = s.toCharArray();
       char[] output = new char[input.length];
   
       for(int i = 0; i < output.length; ++i) {
           output[i] = xor_c(input[i], i);
       }
       return new String(output);
   }
}

然后,如果我们准备接受xor_c中的实际逻辑,则可以通过执行与操作相反的操作直接计算解决方案值。在这种特殊情况下,破译函数实际上也是用来加密的函数。这种想法并不能概括为任意的密码函数。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/280060

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档