php crypt mysql password_PHP 加密用户密码 How to store passwords safely with PHP and MySQL

Do not store password as plain text

Do not try to invent your own password security

Do not ‘encrypt’ passwords

Do not use MD5

Do not use a single site-wide salt

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()不够,可以尝试使用下面的代码

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

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

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值