如何创建一个密码,上面写着“SALT ME!” 什么时候散列?

信息安全 密码 哈希 密码管理 md5
2021-08-08 05:52:47

如何创建一个密码,当使用 md5 直接散列(没有任何盐)时,将返回一个包含 8 个字符“SALT ME!”的字符串。希望一个天真的开发人员在浏览他的用户数据库时会看到“哈希”,意识到他的应用程序的不安全性,最终让世界对每个人都变得更美好。

md5 输出 128 位,即 16 字节。如果我有一个 16 字节的消息,那么获取原始明文密码就相当于一个原图,据我所知,这实际上是不可能的。但是,我只在我的哈希中寻找 8 个特定字节。

在典型计算机上的白天时间范围内获得这样的密码是否可行?如果是这样,我该如何计算这样的密码?

3个回答

MD5 的输出是二进制的:一个 128 位的序列,通常编码为 16 个字节(技术上是 16个八位字节,但让我们使用字节为八位字节的常见约定)。

人类不读取位或字节。他们读字符有许多代码页告诉如何将字符编码为字节,以及类似地,将字节解码为字符。对于几乎所有这些(因为ASCII),低值字节(0 到 31)是“控制字符”,因此不能真正表示为字符。所以没有人真正直接读取 MD5 输出。如果有人正在“读取”哈希值,那么这些值很可能会使用少数常见的约定之一编码成字符。两种最流行的约定是十六进制Base64

对于十六进制,只有数字和字母 'a' 到 'f'(传统上是小写的哈希值)。你不会得到“盐我!” 在十六进制输出中...

对于 Base64,编码使用所有 26 个不重读的拉丁字母(小写和大写)、数字以及“+”和“/”符号。因此,您可以期待“SaltMe”或“SALTME”。现在是可行的,因为 Base64 中的每个字符都编码 6 位,因此 6 个字母的输出仅对应于 36 位。寻找产生“SaltMe”或“SALTME”的密码将在(平均)2 35次尝试中完成,即在几分钟或几小时内使用一些经过适当优化的代码。

但是请注意,实际上花一些时间阅读 Base64 编码的哈希值的人可能有一些,比如说,“社会问题”,因此可能不会像您希望的那样做出反应。

它完成了:当使用 MD5 进行散列时,然后对结果进行 Base64 编码:

  • infjfieq 产量: SALTMEnBrODYbFY0c/tf+Q==
  • lakvqagi 产量: SaltMe+neeRdUB6h99kOFQ==

纯理论上...

预计算哈希的彩虹表集。您可以在其中搜索包含合适字节值的散列值(编辑:需要对预生成完整散列进行一些蛮力强制并进行探测使其更难执行 - 请参阅bonsaiviking对答案的评论),如果存在这样的值(例如一个包含 0xBADBAD 的)。如果存在,那么从彩虹表本身,您可以取回派生该哈希的明文(如果您使用该密码,那么根据定义,它是不安全的,因为任何获得数据库的人都可以反转它,并且所以不建议)。

然而在实践中......

这种方法有很多假设。

  • 在合理规模的组织中,开发人员通常无权访问生产数据库,除非可能是个别故障排除案例。
  • 您假设 MD5 以某种人类可读的格式存储/显示;但它只是一个 16 字节的字节数组,并且实际上取决于开发人员/IT 人员将使用的软件来可视化它。例如,在 Visual Studio 中,调试器通常会按其数值显示字节数组,例如 87,45,34,67,...
  • 您假设正在使用未加盐的 MD5,但可能是其他一些散列函数,显然,散列函数会有所不同,因此无法满足您的要求。
  • 正如其他人已经建议的那样,您不知道它是如何存储的,因为可能已经对其应用了一些额外的转换(例如 Base64),这会使它看起来不同。

但主要是最大的假设是有人正在查看数千/一万/百万/千万/等用户的数据库,并且会从一堆哈希中发现奇数值,甚至从哈希的一部分中发现奇数值。

8 个字节是 64 位,这超出了蛮力。我不知道对 md5 的任何原像攻击,所以你可能不走运。

此外,某些网站会转义或限制您的字符集作为针对 SQLI 的(无效)措施