在给定密码的已知部分的情况下,是否有任何已知的算法、开源程序或白皮书来破解密码?



实际上是我的一个朋友把自己锁在了他创建的加密容器之外。他一定是在输入密码时打错了,因为他无法进入容器。我们知道它应该是什么,而实际的密码肯定是它的一个变体和/或非常相似。我正在寻找代码或白皮书处理这个概念的"模糊"密码破解给定密码的已知部分或密码遵循的已知模式。语言不重要。我已经开发了一种暴力破解密码提示的方法,我需要的是开发一种算法,让我能够智能地尝试破解它,这样我就不必尝试所有可能的组合。然而,我认为其他人已经这样做了。我在某种程度上理解这背后的概念,但我正在寻找代码或白皮书,其中有人可能已经解决了这个问题。

因此,我构建了一个字典(Python,但请随意发送任何语言的示例),使用可能在密码短语中的字符。考虑因素是标准QWERTY键盘上的击键距离,1337个语音等效,以及每个字母都有一个意外的"/"字符,因为它靠近shift键。从那里提供了示例密码短语,并尝试了每个字母。下面是这个例子:http://code.activestate.com/recipes/535171-password-cracker/

import os
from commands import getoutput
known = {
    '_': ('_', ' ', '-', '.', '/'),
    'b': ('b', 'B', '3', '8', '*', 'v', 'V', 'n', 'N', 'g', 'G', 'h', 'H', ' ', '/'),
    'g': ('g', 'G', '6', '^', 'f', 'F', 'h', 'H', 'b', 'B', 'v', 'V', 't', 'T', '/'),
    'l': ('l', 'L', '1', '!', ';', ':', 'k', 'K', 'o', 'O', '.', '>', ',', '<', 'p', 'P', '/'),
    'e': ('e', 'E', '3', '#', '4', '$', 'r', 'R', 'w', 'W', 'd', 'D', '/'),
    'h': ('h', 'H', '4', '$', 'g', 'G', 'j', 'J', 'y', 'Y', 'b', 'B', 'n', 'N', '/'),
    'i': ('i', 'I', '1', '|', '!', '\', 'u', 'U', 'o', 'O', 'k', 'K', '8', '*', '9', '(', '/'),
    't': ('t', 'T', '7', '&', '+', 'r', 'R', 'y', 'Y', 'g', 'G', '4', '5', '%', '6', '^', '/'),
    'r': ('r', 'R', 'e', 'E', 't', 'T', 'f', 'F', '4', '$', '5', '%', '/'),
}
command = 'open-sesame %s' # hey, use your imagination ;)
# I obviously supplied only needed letters for this example, I can't tip you 
# off to the real pass phrase ;) This conveys the general idea....
passwdBasic = 'Big_Leg_Hitter'
def main():
    arrays = [known[ltr] for ltr in passwdBasic]
    start = [ltrs[0] for ltrs in arrays]
    end = [ltrs[-1] for ltrs in arrays]
    indexes = [0] * len(arrays)
    maxes = [len(ltrs)-1 for ltrs in arrays]
    chrs = [ltrs[i] for ltrs, i in zip(arrays, indexes)]
    while chrs != end:
        passx = ''.join(chrs)
        open('tries.txt', 'a+').write(passx + 'n')
        out = getoutput(command)
        if 'wrong password' not in out:
            print 'GOT IT!', passx
            return
        # Next letter
        for i in range(len(indexes)-1, -1, -1):
            if indexes[i] <= maxes[i]-1:
                indexes[i] += 1
                break
            else:
                indexes[i] = 0
        # Make up the chrs
        chrs = [ltrs[i] for ltrs, i in zip(arrays, indexes)]

if __name__ == '__main__':
    main()

虚构的'open-sesame'是一个经过修改的实用程序,用于挂载这种特定类型的加密卷,它不是用python编写的,但已被制成命令行工具,以便该脚本可以与其交互。

几个挑战/研究方向:

  • 如果不小心按了'/'字符而不是shift键,这实际上会在密码短语中添加一个字符,因此可以出现在任何字母之前。这需要在解决方案中考虑。
  • 将其与@rrenaud: http://norvig.com/spell-correct.html
  • 提出的拼写检查器实用程序集成将是很好的
  • 我着迷于贝叶斯概率统计定理的应用,它被用于解决拼写检查问题;我想知道是否有任何关于错误击键的研究,以及在键入某些单词和/或短语时击中某些键而不是其他键的可能性。此逻辑可以应用于密码破解,其方式与拼写检查实用程序非常相似,拼写检查实用程序受益于已知的常见拼写错误列表。我没有错误的击键数据来"训练"神经网络实用程序。

我感谢所有的帮助,我只是想分享我到目前为止的进展,为了大家的利益。

您是否尝试从给定的已知错误密码中枚举编辑?如果你只做了一些编辑(就像打字错误一样),那就没有那么多的可能性了。

它列举了一个级别的编辑,由Norvig在edits1()函数中用于拼写更正的漂亮代码解决。你可以先加深深度,先进行单次编辑,然后是编辑的编辑,编辑的编辑等等

  • 首先你需要你的字符集。特殊字符可能存在吗?大写和小写?数字?

  • 接下来你需要你最初的猜测。可能有2次猜测,第二次将大小写颠倒,因为CAPS LOCK键是按下的。(fuzzY v. fuzzY)

  • 现在你需要迭代所有的可能性…编辑、删除和插入。

    • 你有3组初始猜测
  • 现在你决定你要走多远。也许2次编辑,2次删除,或2次插入…或1编辑1插入,或1删除1插入等

一些JavaScript代码来说明:

var charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
var guesses = {"passWORD":true, "PASSword":true};
function getProps(obj) {
 var lst = [];
 for(var g in obj)
  lst.push(g);
 return lst;
}
function transformEdit(guesses) {
 var lst = getProps(guesses);
 for(var x=0; x<lst.length; x++) {
  var guess = lst[x];
  for(var y=0; y<guess.length; y++) {
   for(var z=0; z<charset.length; z++) {
    guesses[guess.slice(0,y) + charset.charAt(z) + guess.slice(y+1)]=true;
   }
  }
 } 
}
function transformDelete(guesses) {
 var lst = getProps(guesses);
 for(var x=0; x<lst.length; x++) {
  var guess = lst[x];
  for(var y=0; y<guess.length; y++) {
   guesses[guess.slice(0,y) + guess.slice(y+1)]=true;
  }
 }
}
function transformInsert(guesses) {
 var lst = getProps(guesses);
 for(var x=0; x<lst.length; x++) {
  var guess = lst[x];
  for(var y=0; y<guess.length+1; y++) {
   for(var z=0; z<charset.length; z++) {
    guesses[guess.slice(0,y) + charset.charAt(z) + guess.slice(y)]=true;
   }
  }
 } 
}
// not the most efficient way
// but you'll get every possible edit, delete and insert
transformDelete(guesses);
transformInsert(guesses);
transformEdit(guesses);
getProps(guesses).length; //1759604

代码没有提供最有效的解决方案,因为有很多可以避免的重叠,但这是为了生成一个一次性问题的密码列表,所以…

我使用JS对象属性列表作为猜测的哈希集。

可以通过迭代getProps(guess)返回的数组将猜测结果输出到密码列表。

最新更新