【问题标题】:generating password with crypt (32-bits vs 64-bit)使用 crypt 生成密码(32 位与 64 位)
【发布时间】:2015-10-23 23:21:38
【问题描述】:

我正在使用这个函数来生成密码:

function generarPassword($password, $cost=11){
    $salt = strtr(base64_encode(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)), '+', '.');
    $salt='$'.implode('$',array("2y",str_pad($cost,2,"0",STR_PAD_LEFT),$salt));
    return crypt($password,$salt);
}

我的问题是,当我在64位服务器上使用时,结果是这样的:

$2y$11$1ws6drmcqHCWG8wj5bm5s.R8Opc0.JEjXy0.P9UsHjqoxjZQ5GYLW

当我在 32 位服务器上使用它时,结果是这样的:

$2uUq69/OVG3M

所以,我有两个问题:

  1. 为什么会这样? $salt 在两者中的长度相同
  2. 32 位密码是否存在安全问题?

谢谢!

【问题讨论】:

  • 您使用的是 PHP 5.5+ 吗?如果是这样,password_hash() 将负责应用适当的回合/等。而且您不需要独立管理盐(这可能会导致您的问题)。

标签: php security salt crypt


【解决方案1】:

CRYPT_BLOWFISH - 使用盐散列的河豚如下:“$2a$”, “$2x$”或“$2y$”,两位数的成本参数,“$”和 22 个字符 来自字母“./0-9A-Za-z”。使用此之外的字符 salt 中的 range 将导致 crypt() 返回零长度字符串

PHP 5.3.7 之前只支持“$2a$”作为盐前缀:PHP 5.3.7

您的$salt 不符合河豚算法的22 characters from the alphabet 约束。您需要检查生成适当盐的过程。

$salt = strtr(base64_encode(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)), '+', '.');
echo $salt.' ('.strlen($salt).')';
// example: D3Zc0fv8BBLKYnpH0iSV0w== (24)

其次,您使用的是前缀$2y$,它仅在 PHP 5.3.7 之后才受支持。如果您在两个不同的系统上使用此代码,这两个问题都是您需要解决的问题。

【讨论】:

  • 长度应该是正确的,如果你修剪了最后的填充“=”。真正的问题是为什么它可以在 64 位服务器上运行?两个版本的 PHP 是一样的吗?
  • @JayDansand,是的,如果他修剪那些我在代码中任何地方都看不到的字符。我猜 urandom 在两个系统上的返回值都不一样。选择的函数对于生成河豚盐来说不是很好。
  • 同意。带有 MCRYPT_DEV_URANDOM 的 mcrypt_create_iv() 即使在 Linux 服务器上也不能保证良好的熵(如果熵池很小,它不会阻塞),并且在 Windows 上,PHP openssl_random_pseudo_bytes() 在所有情况下都会更好(旧 PHP 版本上的 Windows 错误除外)。这并不重要,但另外 22 个指定的 2^6 字母表中的随机字符将是 132 位熵,而 16 个随机字节提供 128 位。
  • 对,服务器是 32 位的,并且有 PHP5.1.6……也许这就是问题所在。
  • 您有没有推荐我实现的功能,以便生成的密码仍然安全,并且可以在旧服务器/php 和新服务器中使用?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-02
  • 2011-09-28
  • 2013-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多