从MD5哈希函数的特殊应用程序中恢复电子邮件地址

时间:2014-06-02 23:04:01

标签: encryption hash md5

首先,我们将电子邮件地址分成2个字符的字符串 然后,对于每个段s,我们计算以下哈希J:

md5(md5(s) + s + md5(s))  [where + is the string concatenation operator].

最后,我们将所有哈希字符串J连接起来,形成下面的长哈希。

例如:对于helloworld@company.com的输入,我们会计算:

md5(md5('he') + 'he' + md5('he')) +
md5(md5('ll') + 'll' + md5('ll')) +
md5(md5('ow') + 'ow' + md5('ow')) +
...

Long Hash:

f894e71e1551d1833a977df952d0cc9de44a1f9669fbf97d51309a2c6574d5eaa746cdeb9ee1a5df
c771d280d33e5672bf024973657c99bf80cb242d493d5bacc771b3b0b422d5c13595cf3e73cfb1df
91caedee7a6c5f3ce2c283564a39c52d3306d60cbc0e3e33d7ed01e780acb1ccd9174cfea4704eb2
33b0f06e52f6d5aba5a5a89e6122dd55f8efcf024961c1003d116007775d60a0d5781d2e35d747b5
dece2e0e3d79d272e40c8c66555f5525

如何从哈希中恢复电子邮件地址?据我了解," Hash"是单向函数。我只能将它与另一个哈希进行比较,以查看它们是否匹配或生成原始文本的哈希值。

2 个答案:

答案 0 :(得分:2)

虽然一般可能是真的从散列中提取原始消息是不切实际的,但这显然看起来像是一个精心设计的条件的练习,可以打破“加密”


请考虑将电子邮件地址分解为两个字符的细分。如果您将自己限制为只有小写字母(26个字母+2个符号,@.,则只有28 * 28 = 784个可能的双字母组合。即使电子邮件包含小写和大写字母和数字,只有64 * 64 = 4096组合 - 完全在计算限制范围内。

要做的是预先计算搜索空间中所有可能哈希值的rainbow table或表格。你可以用矩阵来做到这一点:

 +----------------------------------+----------------------------------+----------------------------------------+-----------------------------+
 |                a                 |                b                 |                c                       |             ...             |
 +----------------------------------+----------------------------------+----------------------------------------+-----------------------------+
a| md5(md5('aa') + 'aa' + m5('aa')) | md5(md5('ba') + 'ba' + m5('ba')) | md5(md5('ca') + 'ca' + m5('ca'))       |             ...             |
 +----------------------------------+----------------------------------+----------------------------------------+-----------------------------+
b| md5(md5('ab') + 'ab' + m5('ab')) | md5(md5('bb') + 'bb' + m5('bb')) | md5(md5('cb') + 'cb' + m5('cb'))       |             ...             |
 +----------------------------------+----------------------------------+----------------------------------------+-----------------------------+
c| md5(md5('ac') + 'ac' + m5('ac')) | md5(md5('bc') + 'bc' + m5('bc')) | md5(md5('cc') + 'cc' + m5('cc'))       |             ...             |
 +----------------------------------+----------------------------------+----------------------------------------+-----------------------------+
 |               ...                |               ...                |               ...                      |             ...             |
 +----------------------------------+----------------------------------+----------------------------------------+-----------------------------+

但是每次你必须遍历矩阵才能找到匹配 - 慢!

另一种方法是使用一个字典,其中键是哈希值,值是'已解码'字母:

{ 
   md5(md5('aa') + 'aa' + md5('aa')): 'aa',
   md5(md5('ab') + 'ab' + md5('ab')): 'ab',
   md5(md5('ac') + 'ac' + md5('ac')): 'ac',
  ...
}

无论哪种方式,您现在都可以使用所有可能的双字母组合的哈希值。现在您处理输入字符串。由于MD5产生32个字符的长哈希值,因此将输入分解为32个字符的字符串,并对表执行查找:

'f894e71e1551d1833a977df952d0cc9d' => 'he'
'e44a1f9669fbf97d51309a2c6574d5ea' => 'll'
...

答案 1 :(得分:1)

以下是您可以做的事情:

步骤1:将哈希字符串除以32位块

步骤2:从字符串列表中找到2个字符串的所有可能组合,这些字符串可以是字母,数字和任何特殊字符的组合。

步骤3:为该段生成MD5哈希码,将其与纯文本段和相同的哈希码连接,并再次生成MD5哈希码

步骤4:将生成的哈希码与现有哈希码进行比较。如果匹配则将其保存在字符串缓冲区中。迭代此过程直到所有块都被解码。你会得到答案。