好吧,我知道这听起来很糟糕,就像我会用这个来做不道德的事情,但你说的话我不是。
我正在为我的计算机和信息安全课程写一篇论文,我选择的主题是散列方法。我在论文中提到的一点是MD5只是单向的,破解MD5哈希的唯一方法是不断创建字符串并使用MD5函数,然后将其与要破解的哈希值进行比较。 / p>
我想构建一个非常简单的模拟程序,与我的论文一起显示(我们做一个演示文稿,这将是一个很棒的事情),所以我想制定一个算法,每个字符串都有一个字符串可能的字符组合,最多8个字符。例如,输出将是:
a,b,c,...,aa,ab,ac,... ba,bb,bc等等。
如果可能,它需要包括字母,数字和符号。
我部分通过算法,但不幸的是我的编程技巧不能胜任任务。如果有人能为此提供完整的算法,我将非常感激。
同样,如果你认为我是个骗子而且我打算将它用于黑客目的,你就不必留下答案了。
谢谢。 :)
答案 0 :(得分:6)
在Python中,itertools.product几乎可以满足您的所有要求 - 尽管它仅针对一个“重复次数”进行,因此您必须从1到8迭代(不是很难;-)。实质上:
import itertools
import string
# whatever you wish as alphabet (lower/upper, digits, punct, &c)
myalphabet = string.ascii_lowercase + string.ascii_digits
def prods(maxlen, alphabet=myalphabet):
for i in range(1, maxlen+1):
for s in itertools.product(alphabet, repeat=i):
yield ''.join(s)
当然,对于长度为N和K重复的字母表(在您的情况下为8),这确实产生N + N ^ 2 + ... + N ^ K种可能性(对于N = 36和K = 8,可能有2,901,713,047,668种可能性)但是,朋友之间有几万亿的产出! - )
答案 1 :(得分:3)
为了实现这一点,我可能会将整数编码为36(或更多,如果你想要符号)。
1 = 1 2 = 2 ... a = 10 b = 12 ..
等等。
然后你会得到一个数字,比如38并做一些分歧,即:
38/36 = 1 reider 2 = 12 in base 36
然后只需运行一个for循环到你想编码的最大数字,非常大的数字并输出你的编码数字。
只是为了好玩,我为你写了这个:http://pastebin.antiyes.com/index.php?id=327
答案 2 :(得分:1)
“破解MD5哈希”的唯一方法是生成每个可能的字符串并查找冲突。实际上,如果您可以访问原始文件,则可以对其进行修改,使其MD5与您可以创建的其他文件的MD5相匹配。这在a paper at infosec.edu。
中有所描述即使您无法修改原始文件,也存在可用于生成冲突的MD5校验和的rainbow tables。
这些事实使得MD5不适合密码或加密,事实上美国政府已禁止其继续使用安全应用程序。
答案 3 :(得分:0)
如果您已经可以访问密码的哈希版本,那么MD5 is broken to begin with。也就是说,在打破散列值时,使用Rainbow Tables,Dictionary Attacks和Social Engineering优于您的暴力方法可能会更好。也就是说,既然你要求一个算法来生成所有的值,那么以下可能是有益的(C#):
using System;
using System.Text;
namespace PossibiltyIterator
{
class Program
{
static readonly char[] Symbols = {
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '!', '@', '#', '$', '%', '^', '&',
'*', '(', ')', '-', '_', '+', '=', '/', '\\', '[', ']', '{', '}', ';', ':', '\'', '"',
',', '.', '<', '>', '?', '`', '~'
};
const int MaxLength = 8;
static void BuildWord(int currentLength, int desiredLength, char[] word)
{
if (currentLength == desiredLength)
{
Console.WriteLine(word);
}
else
{
for (int value = 0; value < Symbols.Length; ++value)
{
word[currentLength] = Symbols[value];
BuildWord(currentLength + 1, desiredLength, word);
}
}
}
static void Main(String[] args)
{
double totalValues = (Math.Pow(Symbols.Length, MaxLength + 1) - Symbols.Length)/(Symbols.Length - 1);
Console.WriteLine("Warning! You are about to print: {0} values", totalValues);
Console.WriteLine("Press any key to continue...");
Console.ReadKey(true /* intercept */);
for (int desiredLength = 1; desiredLength <= MaxLength; ++desiredLength)
{
BuildWord(0 /* currentLength */, desiredLength, new char[MaxLength]);
}
}
}
}
说实话,这可以进一步优化。因为它构建长度为1的所有“单词”,然后在构建长度为2的单词时第二次起作用。构建长度为MaxLength的单词,然后截断一个字母以构建MaxLength的单词将更为明智 - 1。
以下是优化版本...请注意,它不会按照最初请求的顺序返回单词。
using System;
using System.Text;
namespace PossibiltyIterator
{
class Program
{
static readonly char[] Symbols = {
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '!', '@', '#', '$', '%', '^', '&',
'*', '(', ')', '-', '_', '+', '=', '/', '\\', '[', ']', '{', '}', ';', ':', '\'', '"',
',', '.', '<', '>', '?', '`', '~'
};
const int MaxLength = 8;
static void BuildWord(int currentLength, int desiredLength, char[] word)
{
if (currentLength != desiredLength)
{
for (int value = 0; value < Symbols.Length; ++value)
{
word[currentLength] = Symbols[value];
BuildWord(currentLength + 1, desiredLength, word);
}
word[currentLength] = '\0';
}
Console.WriteLine(word);
}
static void Main(String[] args)
{
double totalValues = (Math.Pow(Symbols.Length, MaxLength + 1) - Symbols.Length)/(Symbols.Length - 1);
char[] word = new char[MaxLength];
Console.WriteLine("Warning! You are about to print: {0} values", totalValues);
Console.WriteLine("Press any key to continue...");
Console.ReadKey(true /* intercept */);
BuildWord(0 /* currentLength */, MaxLength, new char[MaxLength]);
}
}
}
答案 4 :(得分:0)
使用Java示例完成帖子,该示例将仅使用0-9和a-z字符打印出所有可能字符组合的Base64编码MD5:
MessageDigest digest = MessageDigest.getInstance("MD5");
int i = 0;
while (true)
{
String raw = Integer.toString(i, Character.MAX_RADIX);
byte[] md5 = digest.digest(raw.getBytes());
String base64 = new BigInteger(1, md5).toString(16);
System.out.println(raw + " = " + base64);
i++;
}