PHP 加密用户密码 How to store passwords safely with PHP and MySQL

本文深入探讨了如何安全地在PHP中存储用户密码,包括使用强哈希函数、随机盐、缓慢哈希算法等策略,并提供了实例代码。同时,介绍了额外的预防黑客攻击的技巧,如限制登录尝试次数、设置强密码政策等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. Do not store password as plain text
  2. Do not try to invent your own password security
  3. Do not ‘encrypt’ passwords
  4. Do not use MD5
  5. Do not use a single site-wide salt
  6. What you should do
  • Use a cryptographically strong hashing function like bcrypt (see PHP's crypt() function).
  • Use a random salt for each password.
  • Use a slow hashing algorithm to make brute force attacks practically impossible.
  • For bonus points, regenerate the hash every time a users logs in.
$username = 'Admin';
$password = 'gf45_gdf#4hg';

// A higher "cost" is more secure but consumes more processing power
$cost = 10;

// Create a random salt
$salt = strtr(base64_encode(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)), '+', '.');

// Prefix information about the hash so PHP knows how to verify it later.
// "$2a$" Means we're using the Blowfish algorithm. The following two digits are the cost parameter.
$salt = sprintf("$2a$%02d$", $cost) . $salt;

// Value:
// $2a$10$eImiTXuWVxfM37uY4JANjQ==

// Hash the password with the salt
$hash = crypt($password, $salt);

// Value:
// $2a$10$eImiTXuWVxfM37uY4JANjOL.oTxqp7WylW7FCzx2Lc7VLmdJIddZq

 

In the above example we turned a reasonably strong password into a hash that we can safely store in a database. The next time the user logs in we can validate the password as follows:

$username = 'Admin';
$password = 'gf45_gdf#4hg';

// For brevity, code to establish a database connection has been left out

$sth = $dbh->prepare('
  SELECT
    hash
  FROM users
  WHERE
    username = :username
  LIMIT 1
  ');

$sth->bindParam(':username', $username);

$sth->execute();

$user = $sth->fetch(PDO::FETCH_OBJ);

// Hashing the password with its hash as the salt returns the same hash
if ( hash_equals($user->hash, crypt($password, $user->hash)) ) {
  // Ok!
}

 

A few additional tips to prevent user accounts from being hacked:

  • Limit the number of failed login attempts.
  • Require strong passwords.
  • Do not limit passwords to a certain length (remember, you're only storing a hash so length doesn't matter).
  • Allow special characters in passwords, there is no reason not to.

注意:hash_equals (PHP 5 >= 5.6.0) 如果你的php版本 phpversion()不够,可以尝试使用下面的代码

原文:https://alias.io/2010/01/store-passwords-safely-with-php-and-mysql/

 

password_compat

 This library requires PHP >= 5.3.7 OR a version that has the $2y fix backported into it (such as RedHat provides). Note that Debian's 5.3.3 version is NOT supported.

使用前,用下面代码测试当前域名是否可以用这个password_compat

<?php
require "lib/password.php";
echo "Test for functionality of compat library: " . (PasswordCompatbinarycheck() ? "Pass" : "Fail");
echo "n";

 

Usage

Creating Password Hashes

To create a password hash from a password, simply use the password_hash function.

$hash = password_hash($password, PASSWORD_BCRYPT);

 

Note that the algorithm that we chose is PASSWORD_BCRYPT. That's the current strongest algorithm supported. This is the BCRYPT crypt algorithm. It produces a 60 character hash as the result.

 

BCRYPT also allows for you to define a cost parameter in the options array. This allows for you to change the CPU cost of the algorithm:

$hash = password_hash($password, PASSWORD_BCRYPT, array("cost" => 10));

 

That's the same as the default. The cost can range from 4 to 31. I would suggest that you use the highest cost that you can, while keeping response time reasonable (I target between 0.1 and 0.5 seconds for a hash, depending on use-case).

 

Another algorithm name is supported:

    PASSWORD_DEFAULT

This will use the strongest algorithm available to PHP at the current time. Presently, this is the same as specifying PASSWORD_BCRYPT. But in future versions of PHP, it may be updated to use a stronger algorithm if one is introduced. It can also be changed if a problem is identified with the BCRYPT algorithm. Note that if you use this option, you are strongly encouraged to store it in a VARCHAR(255) column to avoid truncation issues if a future algorithm increases the length of the generated hash.

 

It is very important that you should check the return value of password_hash prior to storing it, because a false may be returned if it encountered an error.

 

Verifying Password Hashes

To verify a hash created by password_hash, simply call:

    if (password_verify($password, $hash)) {
        /* Valid */
    } else {
        /* Invalid */
    }

 

That's all there is to it.

 

Rehashing Passwords

From time to time you may update your hashing parameters (algorithm, cost, etc). So a function to determine if rehashing is necessary is available:

    if (password_verify($password, $hash)) {
        if (password_needs_rehash($hash, $algorithm, $options)) {
            $hash = password_hash($password, $algorithm, $options);
            /* Store new hash in db */
        }
    }

 

 

项目地址:https://github.com/ircmaxell/password_compat

下载:password_compat-master

 

转自:PHP 加密用户密码 How to store passwords safely with PHP and MySQL

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值