best algorithm to store passwords in 2016

后端 未结 2 1149
夕颜
夕颜 2021-02-08 03:42

Actually I read many post related to the algorithm for use like md5, sha1 and so on. But I am still not sure which one is the secure and the be

相关标签:
2条回答
  • 2021-02-08 04:04

    Important is, that the algorithm offers a cost factor, which controls the necessary time to calculate a hash. The more time you can invest in calculating a single hash, the more expensive brute-forcing will become (e.g. 100 Giga MD5 per second vs 10 BCrypt per second).

    Today recommended algorithms are BCrypt, PBKDF2 and SCrypt. The algorithm BCrypt is supported by PHP, a wrapper function takes care of the generation of a salt and is future proof.

    // 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);
    
    0 讨论(0)
  • 2021-02-08 04:19

    Incidentally: How to safely store your users' passwords in 2016.

    Your choices are:

    • Argon2 (requires PHP 7.2 or a PHP extension)
    • Scrypt (requires PHP extension)
    • Bcrypt

    If you really need to, also feel free to consider PBKDF2.

    The old standby: Bcrypt

    Given that you're a beginner, you should be writing your password validation like this:

    // 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
        }
    }
    

    Downside to bcrypt:

    • Passwords over 72 characters are truncated.
    • Passwords with a NUL byte will truncate.

    A stop-gap that works around these limitations is built into Password Lock: It pre-hashes passwords with SHA384 then base64-encodes the raw hash before passing to PHP's password API.

    First, create an encryption key and store it outside your document root. (Otherwise, a hacker can just steal the key.)

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

    Now, you can use this key in conjunction with your passwords:

    $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

    The new standard: Argon2 (via Libsodium)

    Unless you're on PHP 7.2 or higher, you'll need to install libsodium and the PHP extension to use Argon2. Password hashing is one of the features that is not provided by 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.
    }
    

    Intermediate: Scrypt

    You'll need the scrypt extension which is available through PECL:

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

    Once that's installed, using it is fairly straightforward:

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

    The only reason to really use scrypt is compatibility; at this point, go with either Argon2 or bcrypt.

    Acceptable but not Great: PBKDF2

    I highly recommend going with Defuse Security's cross-platform Password Hashing library if you need PBKDF2. (You should consider just using password_*, however!)

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

    Any of the above choices are acceptable. Argon2 is probably the most secure, but it's not widely available in PHP yet. Anything absent from this list should be regarded with a healthy dose of skepticism.

    0 讨论(0)
提交回复
热议问题