2016年存储密码的最佳算法

问题描述 投票:11回答:2

实际上我读了许多与使用的算法有关的帖子,如md5,sha1等。但我仍然不确定哪一个是现在使用的安全和最好的。我是网络开发的初学者,我要求全世界所有最优秀的程序员教我并给我看。我希望你们能给我选择和使用它的例子。谢谢

php security web hash
2个回答
17
投票

顺便说一下:How to safely store your users' passwords in 2016

你的选择是:

  • Argon2(需要PHP 7.2或PHP扩展)
  • Scrypt(需要PHP扩展)
  • Bcrypt

如果你真的需要,也可以随意考虑PBKDF2。

旧备用:Bcrypt

鉴于您是初学者,您应该像这样编写密码验证:

// Creating your hashed password:
$hash = password_hash($userPassword, PASSWORD_DEFAULT);

// Checking a user-supplied password against a stored hash:
if (password_verify($userPassword, $hash)) {
    // Login successful.
    if (password_needs_rehash($hash, PASSWORD_DEFAULT)) {
        // Recalculate a new password_hash() and overwrite the one we stored previously
    }
}

下行到bcrypt:

  • 超过72个字符的密码被截断。
  • 具有NUL字节的密码将被截断。

Password Lock内置了一个围绕这些限制的止损:它使用SHA384预先修改密码,然后在传递给PHP的密码API之前对原始哈希进行base64编码。

首先,创建加密密钥并将其存储在文档根目录之外。 (否则,黑客可以窃取密钥。)

$newKey = \Defuse\Crypto\Key::createNewRandomKey();
file_put_contents(
    '/outside/document/root/enckey.txt',
    $newKey->saveToAsciiSafeString()
);

现在,您可以将此密钥与密码结合使用:

$key = Key::loadFromAsciiSafeString(
    file_get_contents('/outside/document/root/enckey.txt')
);

// Hashing a password with PasswordLock:
$storeMe = PasswordLock::hashAndEncrypt($_POST['password'], $key);

// Verifying a password with PasswordLock:
if (PasswordLock::decryptAndVerify($_POST['password'], $storeMe, $key)) {
    // Success!
}

You can now use Argon2 with password_hash() in PHP 7.2

新标准:Argon2(通过Libsodium)

除非你使用的是PHP 7.2或更高版本,否则你需要使用install libsodium and the PHP extension来使用Argon2。密码哈希是sodium_compat未提供的功能之一。

// Password hashing:
$hash_str = sodium_crypto_pwhash_str(
    $password,
    SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
    SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
);
// Password verification:
if (sodium_crypto_pwhash_str_verify($hash_str, $password)) {
    // recommended: wipe the plaintext password from memory
    sodium_memzero($password);

    // Password was valid.
} else {
    // recommended: wipe the plaintext password from memory
    sodium_memzero($password);

    // Password was invalid.
}

中级:Scrypt

您需要通过PECL提供的the scrypt extension

pecl install scrypt
echo "extension=scrypt.so" > /etc/php5/mods-available/scrypt.ini
php5enmod scrypt

一旦安装,使用它是相当简单的:

// Hashing:
$hash = \Password::hash($userProvidedPassword);
// Validation:
if (\Password::check($userProvidedPassword, $hash)) {
    // Logged in successfully.
}

真正使用scrypt的唯一原因是兼容性;此时,请使用Argon2或bcrypt。

Acceptable but not Great: PBKDF2

如果你需要PBKDF2,我强烈建议你去Defuse Security's cross-platform Password Hashing library。 (但是你应该考虑使用password_*!)

$hash = PasswordStorage::create_hash($password);
if (PasswordStorage::verify_password($password, $hash)) {
    // Success
}

任何上述选择都是可以接受的。 Argon2可能是最安全的,但它尚未在PHP中广泛使用。此列表中缺少的任何内容都应被视为怀有健康的怀疑态度。


6
投票

重要的是,该算法提供了一个成本因子,它控制计算哈希的必要时间。你可以投入更多的时间来计算单个哈希值,就会变得更加昂贵的暴力(例如100 Giga MD5 per second与每秒10 BCrypt)。

今天推荐的算法是BCrypt,PBKDF2和SCrypt。 PHP支持算法BCrypt,包装函数负责生成盐,是未来的证据。

// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_DEFAULT);

// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($password, $existingHashFromDb);
© www.soinside.com 2019 - 2024. All rights reserved.