加密密码:什么时候太多了?

时间:2011-06-29 10:39:25

标签: php salt saltedhash

我正在更新我的helper函数库。我想知道密码加密中salt是否过多?

之间有什么区别:

mb_substr(sha1($str . AY_HASH), 5, 10) . mb_substr(sha1(AY_HASH . sha1($str . AY_HASH)), 5, 10) . mb_substr(md5($str . AY_HASH), 5, 10)

简单地说:

sha1(AY_HASH . sha1($str . AY_HASH))

AY_HASHsalt。我应该选择哪个,如果两者都不好,那么最好的替代方案是什么?

2 个答案:

答案 0 :(得分:5)

应为每个密码生成 ,而不是每个密码使用的密码字符串。重用盐意味着攻击者只需要为每个密码创建一个彩虹表,而不是每个密码创建一个彩虹表。

我邀请您阅读我在secure hashing上写的上一个回答。规则很简单:

  • 对所有密码使用单个salt。每个密码使用随机生成的盐。
  • 执行 NOT 重新发送未经修改的哈希(冲突问题,see my previous answer,您需要无限的哈希输入)。
  • 尝试在复杂的操作中创建自己的哈希算法或混合匹配算法。
  • 如果遇到损坏/不安全/快速哈希原语,请使用key strengthening。这增加了攻击者计算彩虹表所需的时间。例如:

function strong_hash($input, $salt = null, $algo = 'sha512', $rounds = 20000) {
  if($salt === null) {
    $salt = crypto_random_bytes(16);
  } else {
    $salt = pack('H*', substr($salt, 0, 32));
  }

  $hash = hash($algo, $salt . $input);

  for($i = 0; $i < $rounds; $i++) {
    // $input is appended to $hash in order to create
    // infinite input.
    $hash = hash($algo, $hash . $input);
  }

  // Return salt and hash. To verify, simply
  // passed stored hash as second parameter.
  return bin2hex($salt) . $hash;
}

function crypto_random_bytes($count) {
  static $randomState = null;

  $bytes = '';

  if(function_exists('openssl_random_pseudo_bytes') &&
      (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN')) { // OpenSSL slow on Win
    $bytes = openssl_random_pseudo_bytes($count);
  }

  if($bytes === '' && is_readable('/dev/urandom') &&
     ($hRand = @fopen('/dev/urandom', 'rb')) !== FALSE) {
    $bytes = fread($hRand, $count);
    fclose($hRand);
  }

  if(strlen($bytes) < $count) {
    $bytes = '';

    if($randomState === null) {
      $randomState = microtime();
      if(function_exists('getmypid')) {
        $randomState .= getmypid();
      }
    }

    for($i = 0; $i < $count; $i += 16) {
      $randomState = md5(microtime() . $randomState);

      if (PHP_VERSION >= '5') {
        $bytes .= md5($randomState, true);
      } else {
        $bytes .= pack('H*', md5($randomState));
      }
    }

    $bytes = substr($bytes, 0, $count);
  }

  return $bytes;
}

如果有的话,你应该使用 bcrypt ,这是未来适应性的。再次,I invite you to my previous answer for a more detailed example

答案 1 :(得分:-1)

没有区别。假设salt对每个用户都是唯一的,那么你想要做的就是多次哈希(通常是1000~10000次)。这会通过迭代哈希的次数来增强哈希值。

应该注意的是,一旦攻击者可以访问您的密码摘要只是时间问题,您应该利用该时间使您的用户群的权限无效,并通知您的用户违规行为。