8

我不确定 crypt() 在散列时使用哪种算法。我查看了 PHP 手册,但它只是说它使用了任何可用的东西。但是我怎么知道它使用的是哪一个,如果它确实使用了一个,如何告诉它使用哪一个?我目前正在使用 MAMP 作为我的开发环境,但我认为必须有一种方法可以通过 PHP 中的语句进行查找。

4

1 回答 1

11

您将算法指定为盐字符串的一部分。例如,从$2a$给你一个 Blowfish 密码开始。如果机器不支持您尝试使用的算法,您将不会得到有意义的结果。您可以尝试通过检查一些预定义的常量来提前找出支持哪些算法,例如CRYPT_BLOWFISH,尽管我注意到这些常量CRYPT_SHA256并不CRYPT_SHA512总是被定义,至少在 PHP 5.2 上是这样。从 PHP 5.3 开始,PHP 拥有自己的算法实现,因此与 PHP 5.2 及更早版本一样,系统在 PHP 编译时可用的内容并不重要。PHP 5.2 的 Suhosin 补丁据称至少添加了 Blowfish,但它的实现似乎与 PHP 5.3 中使用的补丁不兼容。

函数的PHP 文档crypt()确实提供了一些关于如何使用 salt 字符串来指定要使用的算法的信息:

  • CRYPT_STD_DES - 基于标准 DES 的哈希,带有来自字母“./0-9A-Za-z”的两个字符的盐。在 salt 中使用无效字符会导致 crypt() 失败。
  • CRYPT_EXT_DES - 扩展的基于 DES 的散列。“salt”是一个 9 字符的字符串,由一个下划线后跟 4 个字节的迭代计数和 4 个字节的 salt 组成。这些被编码为可打印字符,每个字符 6 位,最低有效字符在前。值 0 到 63 被编码为“./0-9A-Za-z”。在 salt 中使用无效字符会导致 crypt() 失败。
  • CRYPT_MD5 - 以 $1$ 开头的 12 个字符盐的 MD5 散列
  • CRYPT_BLOWFISH - 使用盐的 Blowfish 散列如下:“$2a$”,两位数的成本参数,“$”和字母表中的 22 位数字“./0-9A-Za-z”。在 salt 中使用超出此范围的字符将导致 crypt() 返回零长度字符串。两位数的成本参数是底层基于 Blowfish 的散列算法的迭代计数的以 2 为底的对数,必须在 04-31 范围内,超出此范围的值将导致 crypt() 失败。
  • CRYPT_SHA256 - SHA-256 哈希,带有 16 个字符的盐,前缀为 $5$。如果 salt 字符串以 'rounds=$' 开头,则 N 的数值用于指示应该执行多少次散列循环,很像 Blowfish 上的成本参数。默认轮数为 5000,最小为 1000,最大为 999,999,999。超出此范围的任何 N 选择都将被截断到最近的限制。
  • CRYPT_SHA512 - SHA-512 哈希,带有 16 个字符的盐,前缀为 $6$。如果 salt 字符串以 'rounds=$' 开头,则 N 的数值用于指示应该执行多少次散列循环,很像 Blowfish 上的成本参数。默认轮数为 5000,最小为 1000,最大为 999,999,999。超出此范围的任何 N 选择都将被截断到最近的限制。

因此,要指定您希望使用 Blowfish 对字符串“密码”进行 2^10 次迭代,您可以使用

crypt('password', '$2a$10$XA86t7EJ0xD9OYEUbnTulT');

XA86其中以盐开头的字符串。

最后,如果您想要更多示例,或者只是想为您处理所有这些密码兼容性业务,请查看phpass。它是公共领域,在我的经验中运行良好。除非您指定要与多个系统兼容的哈希,否则它将自动在系统上使用“最佳”算法,在这种情况下(我认为)它使用 MD5。

于 2012-04-21T20:48:51.650 回答