【问题标题】:Real Password Cracker - Codewars Challenge - Javascript真正的密码破解者 - Codewars 挑战 - Javascript
【发布时间】:2020-12-21 01:15:04
【问题描述】:

Codewars 上有一个挑战,要求您破译 SHA-1 哈希。

(我认为)我需要 Crypto 才能这样做。我找到了this example 如何使用 Crypto 从 JS 中的字符串创建 SHA-1 哈希:

let x = "Geek"
function createSha1 (x) {
    const crypto = require('crypto'), 
    let hashPwd = crypto.createHash('sha1').update(x).digest('hex'); 
    return hashPwd;
}

那么基本上我需要做相反的事情,对吗?参数以SHA-1 hash 的形式提供给函数,因此我们需要将其转换为字符串 - 如何解码SHA-1 哈希?因为根据this article,你不能。

朋友建议我需要这样做

生成哈希,然后开始循环并为“a”、“b”、“c”、……“aa”、“ab”、“ac”……等生成它,并在哈希匹配时停止并返回它。

那么要生成“正常”哈希,我会执行以下操作:

function stringToHash(string) {            
  let hash = 0;  
  if (string.length == 0) return hash;  
  for (let i = 0; i < string.length; i++) { 
      let char = string.charCodeAt(i); 
      hash = ((hash << 5) - hash) + char; 
      hash = hash & hash; 
  }  
  return hash; 
} 

当然,我不知道我应该使用什么字符串作为参数,因为 Codewars 已经将 SHA-1 哈希作为参数提供给我们:e6fb06210fafc02fd7479ddbed2d042cc3a5155e

这是本网站的本质,但我不想立即发布对这一挑战的答案。如果可能,请在可行的解决方案之前先给出提示/方向。

谢谢!

【问题讨论】:

    标签: javascript hash


    【解决方案1】:

    蛮力或字典攻击

    一般来说,您不能反转哈希值。相反,您可以做的是为输入数据尝试各种可能的候选者,对它们进行哈希处理,然后检查您是否得到了正确的答案。这就是大多数“密码哈希破解”在实践中的工作方式,使用各种完善的工具(hashcat、开膛手约翰等)和在线服务,但这可能无关紧要,因为您需要自己编写解决方案。

    决定您找到解决方案的速度的主要因素是您选择的候选解决方案。循环遍历所有字母并按照您朋友的建议尝试所有可能的组合 - 蛮力解决方案 - 是一种可能性。值得注意的是,只有在你循环正确的“字母”时它才会成功——如果你只尝试小写字母,那么你会故意忽略包含数字或大写字母或其他符号的选项。

    另一个常用的选项是假设密码很弱并运行“字典攻击”,尝试各种比随机字母序列更可能被人类选择的选项。可能是字面词典,尝试英文单词;它可能是已知常用密码的列表(例如https://github.com/danielmiessler/SecLists 有一些类似的列表),或者它可能是结合了一些“变异规则”的字典 - 例如如果列表中包含“password”,破解工具可能会自动生成并尝试“password2”和“Password”以及“passw0rd”等选项。

    在您的特定情况下,密码足够弱,因此暴力破解和字典攻击都可以使用。对于更困难的哈希,情况并非如此。

    【讨论】:

      【解决方案2】:

      理想的加密哈希专门设计为单向函数,因此无法简单地应用逆变换来获取纯文本。您应该注意的其他一点是由于哈希函数的压缩特性,您会遇到鸽子洞原理的问题,这意味着多个事物可以哈希到相同的值。

      有几种方法可以解决这个问题,但不需要您创建逆运算。

      暴力破解

      正如您的朋友所说,最简单的方法就是尝试暴力破解哈希。假设他们选择了 6 个字符长的东西,应该不到一秒钟。如果您对密码的性质一无所知,那么您的工作会更容易。例如,如果您被告知密码长度可能在 4-6 个字符之间,并且它包含至少一个数字和大写字母,您可以创建一个字符集以在您的蛮力中使用。这假设密码是直接哈希或带有一些已知的盐。

      彩虹桌

      这在某种程度上与暴力破解有关,但有人已经花费了时间并尽可能多地预先计算了可能的哈希值。您可以在线找到这些表格,并且只需查找您的哈希值。最常见的密码、单词、短语和字母数字组合已被列举出来,并且可以在几毫秒内进行查找。同样,这些假设值在没有盐等的情况下通过哈希运行。

      长度扩展

      使用 sha1,您可以使用称为长度扩展的东西简单地伪造哈希到相同精确值的东西。这可能超出了您的需要,但如果您真的对密码分析感兴趣,那么值得一看。

      【讨论】:

        【解决方案3】:

        我不使用那个网站,所以不熟悉格式。

        它希望你暴力破解它,可以让它通过测试但不能通过尝试,它总是超时

        这是代码,知道它只会是 codetest 我们可以减少字符集,但它仍然超时。也许你知道为什么。

        const crypto = require('crypto');
        
        const alpha = 'abcdefghijklmnopqrstuvwxyz';
        
        function* permutator(length = 4, prev = "") {
          if (length <= 0) {
            yield prev;
            return;
          }
          for (const char of [...alpha])
            yield* permutator(length - 1, prev + char);
        }
        
        function passwordCracker(hash) {
          const it = permutator();
        
          while (true) {
            const v = it.next().value
            if (v && crypto.createHash('sha1').update(v).digest('hex') === hash)
              return v
          }
        }
        

        编辑,它暗示它期望看到至少 5 个字符,如果你伪造它,类似于:

        function passwordCracker(hash) {
          // Good Luck
          let map = {
            'e6fb06210fafc02fd7479ddbed2d042cc3a5155e': 'code',
            'a94a8fe5ccb19ba61c4c0873d391e987982fbbd3': 'test',
          }
          return map[hash]; 
        }
        

        错误:

        Test Results:
         Fixed tests
         testing...
        expected undefined to equal 'try'
        ...
         harder testing...
        expected undefined to equal 'cgggq'
        

        这意味着你不能用减少的字符集作弊,它需要是a-z,向后工作(因为它会在 5 之前通过)并且至少是 5 长。

        在我的电脑上,上面的代码花费的时间超过了 12 秒,这是限制:(

        【讨论】:

        • 如果你找出原因,请联系我,我对我做错了什么感兴趣
        猜你喜欢
        • 2019-11-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-21
        • 2019-10-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多