如何确定使用了哪种类型的编码/加密?

信息安全 加密 密码学 编码 密码分析
2021-08-10 23:12:36

有没有办法找到正在使用的加密/编码类型?例如,我正在测试一个 Web 应用程序,它以加密格式 ( WeJcFMQ/8+8QJ/w0hHh+0g==) 将密码存储在数据库中。如何确定正在使用什么散列或加密?

4个回答

您的示例字符串 ( WeJcFMQ/8+8QJ/w0hHh+0g==) 是 16 个字节序列的 Base64 编码,看起来不像有意义的 ASCII 或 UTF-8。如果这是为密码验证而存储的值(即不是真正的“加密”密码,而是“散列”密码),那么这可能是对密码计算的散列函数的结果;具有 128 位输出的经典散列函数是 MD5。但这可能是关于任何事情的。

了解这一点的“正常”方法是查看应用程序代码。应用程序代码以有形的、胖的方式体现(服务器上的可执行文件、某处的源代码……),它没有也不能像密钥那样受到保护。所以逆向工程是“要走的路”。

除非进行逆向工程,否则您可以进行一些实验来尝试做出有根据的猜测:

  • 如果同一用户“更改”他的密码但重复使用相同的密码,存储的值是否会更改?如果是,那么部分值可能是随机的“盐”或 IV(假设对称加密)。
  • 假设该值与给定用户的密码是确定的,如果两个用户选择相同的密码,是否会产生相同的存储值?如果不是,那么用户名可能是计算的一部分。您可能想尝试计算 MD5("username:password") 或其他类似的变体,以查看是否匹配。
  • 密码长度有限制吗?也就是说,如果您设置了一个 40 个字符的密码,并且仅通过键入前 39 个字符无法成功验证,那么这意味着所有字符都很重要,这意味着这确实是密码散列,而不是加密(存储的值用于验证密码,但无法仅从存储的值中恢复密码)。

编辑:我刚刚注意到一个非常酷的名为hashID的脚本。这个名字几乎描述了它。

~~~

一般来说,利用经验做出有根据的猜测是这些事情的完成方式。

这是一个包含大量哈希输出的列表,以便您了解每个输出的外观并创建签名/模式或仅进行光学验证。

您首先要注意两个主要事项:

  • 散列的长度(每个散列函数都有特定的输出长度)
  • 使用的字母表(都是英文字母吗?数字 0-9 和 AF 是十六进制的?如果有的话,有什么特殊字符?)

一些密码破解程序(例如开膛手约翰)在输入上应用一些模式匹配来猜测所使用的算法,但这仅适用于通用哈希。例如,如果您采用任何散列输出并将每个字母旋转 1,大多数模式匹配方案都会失败。

您发布的是 16 个字节(128 位)的 base 64 编码数据。它是 base 64 编码的事实并不能告诉我们太多,因为 base 64 不是一种加密/散列算法,它是将二进制数据编码为文本的一种方式。这意味着该块包含一条有用的信息,即输出长度为 16 个字节。我们可以将其与常用方案的块大小进行比较,并找出它不可能是什么。到目前为止,最常见的方案是:

接下来我们需要做的是查看其他密文块,以找出以下问题的答案:

  • 所有密文的长度是否相同,即使输入长度不同?

如果不是所有块的长度都相同,那么您不是在看散列算法,而是在看加密算法。由于输出将始终是底层块大小的倍数,因此存在不能被 16 个字节整除的块意味着它不能是 AES,因此必须是 DES 或 3DES。

如果您有能力输入密码并观察输出,则可以很快确定。只需输入 17 个字符的密码并查看长度。如果它的 16 字节你有 MD5,20 字节表示 SHA-1,24 字节表示 DES 或 3DES,32 字节表示 AES。

如果这确实是一个简单的密码哈希,我们也许可以使用谷歌来破解它但是,使用所有这些斜杠和加号很难搜索 Base64,所以让我们首先将该哈希转换为十六进制:

$ perl -MMIME::Base64 -le 'print unpack "H*", decode_base64 "WeJcFMQ/8+8QJ/w0hHh+0g=="'
59e25c14c43ff3ef1027fc3484787ed2

好的,现在我们可以谷歌了目前,我只收到来自md5this.com的一次点击——尽管显然很快就会有更多点击,包括这篇文章。

不幸的是(或者也许幸运的是,取决于您的观点),我们没有足够的幸运能够真正找到原像(该网站目前将此哈希列为“正在破解...”),但事实上它确实在该列表中强烈建议它确实是真实密码的未加盐 MD5 哈希。