你如何使用 bcrypt 在 PHP 中散列密码?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4795385/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you use bcrypt for hashing passwords in PHP?
提问by Vilx-
Every now and then I hear the advice "Use bcrypt for storing passwords in PHP, bcrypt rules".
我时不时地听到“使用 bcrypt 在 PHP 中存储密码,bcrypt 规则”的建议。
But what is bcrypt
? PHP doesn't offer any such functions, Wikipedia babbles about a file-encryption utility and Web searches just reveal a few implementations of Blowfishin different languages. Now Blowfish is also available in PHP via mcrypt
, but how does that help with storing passwords? Blowfish is a general purpose cipher, it works two ways. If it could be encrypted, it can be decrypted. Passwords need a one-way hashing function.
但什么是bcrypt
?PHP 不提供任何这样的功能,维基百科喋喋不休地谈论一个文件加密实用程序,而网络搜索只是揭示了一些不同语言的Blowfish实现。现在 Blowfish 也可以通过 PHP 在 PHP 中使用mcrypt
,但是这对存储密码有什么帮助?Blowfish 是一种通用密码,它有两种工作方式。如果可以加密,则可以解密。密码需要一种单向散列函数。
What is the explanation?
解释是什么?
采纳答案by Andrew Moore
bcrypt
is a hashing algorithm which is scalable with hardware (via a configurable number of rounds). Its slowness and multiple rounds ensures that an attacker must deploy massive funds and hardware to be able to crack your passwords. Add to that per-password salts(bcrypt
REQUIRES salts) and you can be sure that an attack is virtually unfeasible without either ludicrous amount of funds or hardware.
bcrypt
是一种可随硬件扩展的散列算法(通过可配置的轮数)。它的缓慢和多轮确保攻击者必须部署大量资金和硬件才能破解您的密码。加上每个密码的盐(bcrypt
REQUIRES salts),你可以确定,如果没有可笑的资金或硬件,攻击实际上是不可行的。
bcrypt
uses the Eksblowfishalgorithm to hash passwords. While the encryption phase of Eksblowfishand Blowfishare exactly the same, the key schedule phase of Eksblowfishensures that any subsequent state depends on both salt and key (user password), and no state can be precomputed without the knowledge of both. Because of this key difference, bcrypt
is a one-way hashing algorithm.You cannot retrieve the plain text password without already knowing the salt, rounds and key(password). [Source]
bcrypt
使用Eksblowfish算法来散列密码。虽然Eksblowfish和Blowfish的加密阶段完全相同,但Eksblowfish的密钥调度阶段确保任何后续状态都取决于盐和密钥(用户密码),并且在不知道两者的情况下无法预先计算任何状态。由于这一关键区别,bcrypt
是一种单向散列算法。如果不知道 salt、rounds和 key(密码),您将无法检索纯文本密码。[来源]
How to use bcrypt:
如何使用 bcrypt:
Using PHP >= 5.5-DEV
使用 PHP >= 5.5-DEV
Password hashing functions have now been built directly into PHP >= 5.5. You may now use password_hash()
to create a bcrypt
hash of any password:
密码散列函数现在已直接内置到 PHP >= 5.5 中。您现在可以使用password_hash()
来创建bcrypt
任何密码的哈希:
<?php
// Usage 1:
echo password_hash('rasmuslerdorf', PASSWORD_DEFAULT)."\n";
// y$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// For example:
// y$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a
// Usage 2:
$options = [
'cost' => 11
];
echo password_hash('rasmuslerdorf', PASSWORD_BCRYPT, $options)."\n";
// yDP.V0nO7YI3iSki4qog6OQI5eiO6Jnjsqg7vdnb.JgGIsxniOn4C
To verify a user provided password against an existing hash, you may use the password_verify()
as such:
要根据现有哈希验证用户提供的密码,您可以使用以下password_verify()
方法:
<?php
// See the password_hash() example to see where this came from.
$hash = 'y$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq';
if (password_verify('rasmuslerdorf', $hash)) {
echo 'Password is valid!';
} else {
echo 'Invalid password.';
}
Using PHP >= 5.3.7, < 5.5-DEV (also RedHat PHP >= 5.3.3)
使用 PHP >= 5.3.7, < 5.5-DEV(还有 RedHat PHP >= 5.3.3)
There is a compatibility libraryon GitHubcreated based on the source code of the above functions originally written in C, which provides the same functionality. Once the compatibility library is installed, usage is the same as above (minus the shorthand array notation if you are still on the 5.3.x branch).
GitHub 上有一个兼容库,基于上述最初用 C 编写的函数的源代码创建,提供相同的功能。安装兼容性库后,用法与上述相同(如果您仍在 5.3.x 分支上,则减去速记数组符号)。
Using PHP < 5.3.7 (DEPRECATED)
使用 PHP < 5.3.7 (已弃用)
You can use crypt()
function to generate bcrypt hashes of input strings. This class can automatically generate salts and verify existing hashes against an input. If you are using a version of PHP higher or equal to 5.3.7, it is highly recommended you use the built-in function or the compat library. This alternative is provided only for historical purposes.
您可以使用crypt()
函数来生成输入字符串的 bcrypt 哈希值。这个类可以自动生成盐并根据输入验证现有的哈希值。如果您使用的是高于或等于 5.3.7 的 PHP 版本,强烈建议您使用内置函数或 compat 库。此替代方案仅用于历史目的。
class Bcrypt{
private $rounds;
public function __construct($rounds = 12) {
if (CRYPT_BLOWFISH != 1) {
throw new Exception("bcrypt not supported in this installation. See http://php.net/crypt");
}
$this->rounds = $rounds;
}
public function hash($input){
$hash = crypt($input, $this->getSalt());
if (strlen($hash) > 13)
return $hash;
return false;
}
public function verify($input, $existingHash){
$hash = crypt($input, $existingHash);
return $hash === $existingHash;
}
private function getSalt(){
$salt = sprintf('a$%02d$', $this->rounds);
$bytes = $this->getRandomBytes(16);
$salt .= $this->encodeBytes($bytes);
return $salt;
}
private $randomState;
private function getRandomBytes($count){
$bytes = '';
if (function_exists('openssl_random_pseudo_bytes') &&
(strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN')) { // OpenSSL is slow on Windows
$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 ($this->randomState === null) {
$this->randomState = microtime();
if (function_exists('getmypid')) {
$this->randomState .= getmypid();
}
}
for ($i = 0; $i < $count; $i += 16) {
$this->randomState = md5(microtime() . $this->randomState);
if (PHP_VERSION >= '5') {
$bytes .= md5($this->randomState, true);
} else {
$bytes .= pack('H*', md5($this->randomState));
}
}
$bytes = substr($bytes, 0, $count);
}
return $bytes;
}
private function encodeBytes($input){
// The following is code from the PHP Password Hashing Framework
$itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$output = '';
$i = 0;
do {
$c1 = ord($input[$i++]);
$output .= $itoa64[$c1 >> 2];
$c1 = ($c1 & 0x03) << 4;
if ($i >= 16) {
$output .= $itoa64[$c1];
break;
}
$c2 = ord($input[$i++]);
$c1 |= $c2 >> 4;
$output .= $itoa64[$c1];
$c1 = ($c2 & 0x0f) << 2;
$c2 = ord($input[$i++]);
$c1 |= $c2 >> 6;
$output .= $itoa64[$c1];
$output .= $itoa64[$c2 & 0x3f];
} while (true);
return $output;
}
}
You can use this code like this:
您可以像这样使用此代码:
$bcrypt = new Bcrypt(15);
$hash = $bcrypt->hash('password');
$isGood = $bcrypt->verify('password', $hash);
Alternatively, you may also use the Portable PHP Hashing Framework.
或者,您也可以使用Portable PHP Hashing Framework。
回答by ircmaxell
So, you want to use bcrypt? Awesome!However, like other areas of cryptography, you shouldn't be doing it yourself. If you need to worry about anything like managing keys, or storing salts or generating random numbers, you're doing it wrong.
那么,你想使用 bcrypt 吗?惊人的!但是,与密码学的其他领域一样,您不应该自己动手。如果您需要担心诸如管理密钥、存储盐或生成随机数之类的事情,那您就错了。
The reason is simple: it's so trivially easy to screw up bcrypt. In fact, if you look at almost every piece of code on this page, you'll notice that it's violating at least one of these common problems.
原因很简单:搞砸 bcrypt太容易了。事实上,如果您查看此页面上的几乎每一段代码,您会注意到它至少违反了这些常见问题中的一个。
Face It, Cryptography is hard.
面对现实,密码学很难。
Leave it for the experts. Leave it for people whose job it is to maintain these libraries. If you need to make a decision, you're doing it wrong.
留给专家吧。把它留给那些负责维护这些库的人。如果你需要做出决定,那你就做错了。
Instead, just use a library. Several exist depending on your requirements.
相反,只需使用库。根据您的要求,存在几种。
Libraries
图书馆
Here is a breakdown of some of the more common APIs.
以下是一些更常见的 API 的细分。
PHP 5.5 API - (Available for 5.3.7+)
PHP 5.5 API -(适用于 5.3.7+)
Starting in PHP 5.5, a new API for hashing passwords is being introduced. There is also a shim compatibility library maintained (by me) for 5.3.7+. This has the benefit of being a peer-reviewed and simpleto use implementation.
从 PHP 5.5 开始,引入了用于散列密码的新 API。还有一个(由我)为 5.3.7+ 维护的 shim 兼容性库。这具有经过同行评审且易于使用的实施的好处。
function register($username, $password) {
$hash = password_hash($password, PASSWORD_BCRYPT);
save($username, $hash);
}
function login($username, $password) {
$hash = loadHashByUsername($username);
if (password_verify($password, $hash)) {
//login
} else {
// failure
}
}
Really, it's aimed to be extremely simple.
真的,它的目标是非常简单。
Resources:
资源:
- Documentation: on PHP.net
- Compatibility Library: on GitHub
- PHP's RFC: on wiki.php.net
- 文档:在 PHP.net 上
- 兼容性库:在 GitHub 上
- PHP 的 RFC:在 wiki.php.net 上
Zend\Crypt\Password\Bcrypt (5.3.2+)
Zend\Crypt\Password\Bcrypt (5.3.2+)
This is another API that's similar to the PHP 5.5 one, and does a similar purpose.
这是另一个类似于 PHP 5.5 的 API,并且具有类似的目的。
function register($username, $password) {
$bcrypt = new Zend\Crypt\Password\Bcrypt();
$hash = $bcrypt->create($password);
save($user, $hash);
}
function login($username, $password) {
$hash = loadHashByUsername($username);
$bcrypt = new Zend\Crypt\Password\Bcrypt();
if ($bcrypt->verify($password, $hash)) {
//login
} else {
// failure
}
}
Resources:
资源:
- Documentation: on Zend
- Blog Post: Password Hashing With Zend Crypt
- 文档:在 Zend 上
- 博客文章:使用 Zend Crypt 进行密码散列
PasswordLib
密码库
This is a slightly different approach to password hashing. Rather than simply supporting bcrypt, PasswordLib supports a large number of hashing algorithms. It's mainly useful in contexts where you need to support compatibility with legacy and disparate systems that may be outside of your control. It supports a large number of hashing algorithms. And is supported 5.3.2+
这是一种稍微不同的密码散列方法。PasswordLib 不仅支持 bcrypt,还支持大量散列算法。它主要在您需要支持与可能不受您控制的旧系统和不同系统的兼容性的上下文中很有用。它支持大量的散列算法。并支持 5.3.2+
function register($username, $password) {
$lib = new PasswordLib\PasswordLib();
$hash = $lib->createPasswordHash($password, 'y$', array('cost' => 12));
save($user, $hash);
}
function login($username, $password) {
$hash = loadHashByUsername($username);
$lib = new PasswordLib\PasswordLib();
if ($lib->verifyPasswordHash($password, $hash)) {
//login
} else {
// failure
}
}
References:
参考:
- Source Code / Documentation: GitHub
- 源代码/文档:GitHub
PHPASS
PHPASS
This is a layer that does support bcrypt, but also supports a fairly strong algorithm that's useful if you do not have access to PHP >= 5.3.2... It actually supports PHP 3.0+ (although not with bcrypt).
这是一个确实支持 bcrypt 的层,但也支持相当强大的算法,如果您无法访问 PHP >= 5.3.2,这将很有用......它实际上支持 PHP 3.0+(尽管不支持 bcrypt)。
function register($username, $password) {
$phpass = new PasswordHash(12, false);
$hash = $phpass->HashPassword($password);
save($user, $hash);
}
function login($username, $password) {
$hash = loadHashByUsername($username);
$phpass = new PasswordHash(12, false);
if ($phpass->CheckPassword($password, $hash)) {
//login
} else {
// failure
}
}
Resources
资源
- Code: cvsweb
- Project Site: on OpenWall
- A review of the < 5.3.0 algorithm: on StackOverflow
- 代码:cvsweb
- 项目地点:在 OpenWall 上
- < 5.3.0 算法回顾:在 StackOverflow 上
Note:Don't use the PHPASS alternatives that are not hosted on openwall, they are different projects!!!
注意:不要使用未托管在 openwall 上的 PHPASS 替代品,它们是不同的项目!!!
About BCrypt
关于 BCrypt
If you notice, every one of these libraries returns a single string. That's because of how BCrypt works internally. And there are a TON of answers about that. Here are a selection that I've written, that I won't copy/paste here, but link to:
如果您注意到,这些库中的每一个都返回一个字符串。这是因为 BCrypt 的内部运作方式。对此有很多答案。这是我写的一个选择,我不会在这里复制/粘贴,而是链接到:
- Fundamental Difference Between Hashing And Encryption Algorithms- Explaining the terminology and some basic information about them.
- About reversing hashes without rainbow tables- Basically why we should use bcrypt in the first place...
- Storing bcrypt Hashes- basically why is the salt and algorithm included in the hash result.
- How to update the cost of bcrypt hashes- basically how to choose and then maintain the cost of the bcrypt hash.
- How to hash long passwords with bcrypt- explaining the 72 character password limit of bcrypt.
- How bcrypt uses salts
- Best practices of salting and peppering passwords- Basically, don't use a "pepper"
- Migrating old
md5
passwords to bcrypt
- 散列和加密算法之间的基本区别- 解释术语和有关它们的一些基本信息。
- 关于在没有彩虹表的情况下反转哈希- 基本上为什么我们应该首先使用 bcrypt ......
- 存储 bcrypt 哈希- 基本上为什么盐和算法包含在哈希结果中。
- 如何更新 bcrypt 哈希的成本——基本上是如何选择和维护 bcrypt 哈希的成本。
- 如何使用 bcrypt 散列长密码- 解释bcrypt的 72 个字符密码限制。
- bcrypt 如何使用盐
- 盐渍和胡椒密码的最佳实践- 基本上,不要使用“胡椒”
- 将旧
md5
密码迁移到 bcrypt
Wrap Up
包起来
There are many different choices. Which you choose is up to you. However, I would HIGHLYrecommend that you use one of the above libraries for handling this for you.
有很多不同的选择。您选择哪个取决于您。但是,我强烈建议您使用上述库之一来为您处理此问题。
Again, if you're using crypt()
directly, you're probably doing something wrong. If your code is using hash()
(or md5()
or sha1()
) directly, you're almost definitely doing something wrong.
同样,如果你crypt()
直接使用,你可能做错了什么。如果您的代码直接使用hash()
(or md5()
or sha1()
),那么您几乎肯定做错了什么。
Just use a library...
只需使用图书馆...
回答by Arkh
You'll get a lot of information in Enough With The Rainbow Tables: What You Need To Know About Secure Password Schemesor Portable PHP password hashing framework.
您将在彩虹表足够了:您需要了解的安全密码方案或便携式 PHP 密码散列框架中获得大量信息。
The goal is to hash the password with something slow, so someone getting your password database will die trying to brute force it (a 10 ms delay to check a password is nothing for you, a lot for someone trying to brute force it). Bcryptis slow and can be used with a parameter to choose how slow it is.
目标是用一些缓慢的东西来散列密码,所以有人在尝试蛮力时会死掉你的密码数据库(检查密码的延迟 10 毫秒对你来说没什么,对于试图蛮力的人来说很多)。Bcrypt很慢,可以用一个参数来选择它有多慢。
回答by coreyward
You can create a one-way hash with bcrypt using PHP's crypt()
function and passing in an appropriate Blowfish salt. The most important of the whole equation is that A) the algorithm hasn't been compromised and B) you properly salt each password. Don't use an application-wide salt; that opens up your entire application to attack from a single set of Rainbow tables.
您可以使用 PHP 的crypt()
函数并传入适当的 Blowfish 盐,使用 bcrypt 创建单向哈希。整个等式中最重要的是 A) 算法没有受到损害,B)您正确地为每个密码加盐。不要使用应用范围内的盐;这会打开您的整个应用程序以从一组 Rainbow 表进行攻击。
回答by Jon Hulka
Edit: 2013.01.15 - If your server will support it, use martinstoeckli's solutioninstead.
编辑:2013.01.15 - 如果您的服务器支持它,请改用martinstoeckli 的解决方案。
Everyone wants to make this more complicated than it is. The crypt() function does most of the work.
每个人都想让这比它更复杂。crypt() 函数完成了大部分工作。
function blowfishCrypt($password,$cost)
{
$chars='./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$salt=sprintf('y$%02d$',$cost);
//For PHP < PHP 5.3.7 use this instead
// $salt=sprintf('a$%02d$',$cost);
//Create a 22 character salt -edit- 2013.01.15 - replaced rand with mt_rand
mt_srand();
for($i=0;$i<22;$i++) $salt.=$chars[mt_rand(0,63)];
return crypt($password,$salt);
}
Example:
例子:
$hash=blowfishCrypt('password',10); //This creates the hash
$hash=blowfishCrypt('password',12); //This creates a more secure hash
if(crypt('password',$hash)==$hash){ /*ok*/ } //This checks a password
I know it should be obvious, but please don't use 'password' as your password.
我知道这应该很明显,但请不要使用“密码”作为您的密码。
回答by martinstoeckli
Version 5.5 of PHP will have built-in support for BCrypt, the functions password_hash()
and password_verify()
. Actually these are just wrappers around the function crypt()
, and shall make it easier to use it correctly. It takes care of the generation of a safe random salt, and provides good default values.
PHP 5.5 版将内置对 BCrypt、函数password_hash()
和password_verify()
. 实际上,这些只是函数的包装器crypt()
,可以更容易地正确使用它。它负责安全随机盐的生成,并提供良好的默认值。
The easiest way to use this functions will be:
使用此功能的最简单方法是:
$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);
$isPasswordCorrect = password_verify($password, $existingHashFromDb);
This code will hash the password with BCrypt (algorithm 2y
), generates a random salt from the OS random source, and uses the default cost parameter (at the moment this is 10). The second line checks, if the user entered password matches an already stored hash-value.
此代码将使用 BCrypt(算法2y
)散列密码,从操作系统随机源生成随机盐,并使用默认成本参数(目前为 10)。第二行检查用户输入的密码是否与已存储的哈希值匹配。
Should you want to change the cost parameter, you can do it like this, increasing the cost parameter by 1, doubles the needed time to calculate the hash value:
如果要更改成本参数,可以这样做,将成本参数增加 1,将计算哈希值所需的时间加倍:
$hash = password_hash($password, PASSWORD_BCRYPT, array("cost" => 11));
In contrast to the "cost"
parameter, it is best to omit the "salt"
parameter, because the function already does its best to create a cryptographically safe salt.
与"cost"
参数相反,最好省略"salt"
参数,因为该函数已经尽力创建加密安全的盐。
For PHP version 5.3.7 and later, there exists a compatibility pack, from the same author that made the password_hash()
function. For PHP versions before 5.3.7 there is no support for crypt()
with 2y
, the unicode safe BCrypt algorithm. One could replace it instead with 2a
, which is the best alternative for earlier PHP versions.
对于 PHP 5.3.7 及更高版本,存在一个兼容包,来自制作该password_hash()
功能的同一作者。对于 5.3.7 之前的 PHP 版本,不支持crypt()
with 2y
,unicode 安全的 BCrypt 算法。可以将其替换为2a
,这是早期 PHP 版本的最佳选择。
回答by FYA
Current thinking: hashes should be the slowest available, not the fastest possible. This suppresses rainbow tableattacks.
目前的想法:散列应该是可用的最慢的,而不是最快的。这会抑制彩虹表攻击。
Also related, but precautionary: An attacker should never have unlimited access to your login screen. To prevent that: Set up an IP address tracking table that records every hit along with the URI. If more than 5 attempts to login come from the same IP address in any five minute period, block with explanation. A secondary approach is to have a two-tiered password scheme, like banks do. Putting a lock-out for failures on the second pass boosts security.
同样相关,但要预防:攻击者永远不应无限制地访问您的登录屏幕。为防止这种情况:设置一个 IP 地址跟踪表,记录每次命中以及 URI。如果在任何五分钟内来自同一 IP 地址的登录尝试超过 5 次,则阻止并提供解释。第二种方法是采用两层密码方案,就像银行一样。在第二次通过时锁定失败可以提高安全性。
Summary: slow down the attacker by using time-consuming hash functions. Also, block on too many accesses to your login, and add a second password tier.
总结:通过使用耗时的哈希函数来减缓攻击者的速度。此外,阻止过多访问您的登录信息,并添加第二个密码层。
回答by Synchro
Here's an updated answer to this old question!
这是这个老问题的更新答案!
The right way to hash passwords in PHP since 5.5 is with password_hash()
, and the right way to verify them is with password_verify()
, and this is still true in PHP 8.0. These functions use bcrypt hashes by default, but other stronger algorithms have been added. You can alter the work factor (effectively how "strong" the encryption is) via the password_hash
parameters.
自 5.5 以来password_hash()
,在 PHP 中散列密码的正确方法是使用password_verify()
,验证它们的正确方法是使用,这在 PHP 8.0 中仍然适用。这些函数默认使用 bcrypt 哈希,但已添加其他更强大的算法。您可以通过password_hash
参数更改工作系数(有效加密的“强度”)。
However, while it's still plenty strong enough, bcrypt is no longer considered state-of-the-art; a better set of password hash algorithms has arrived called Argon2, with Argon2i, Argon2d, and Argon2id variants. The difference between them (as described here):
然而,虽然它仍然足够强大,但bcrypt 不再被认为是最先进的;一组更好的密码哈希算法已经出现,称为Argon2,具有 Argon2i、Argon2d 和 Argon2id 变体。(如描述他们之间的差别在这里):
Argon2 has one primary variant: Argon2id, and two supplementary variants: Argon2d and Argon2i. Argon2d uses data-depending memory access, which makes it suitable for cryptocurrencies and proof-of-work applications with no threats from side-channel timing attacks. Argon2i uses data-independent memory access, which is preferred for password hashing and password-based key derivation. Argon2id works as Argon2i for the first half of the first iteration over the memory, and as Argon2d for the rest, thus providing both side-channel attack protection and brute-force cost savings due to time-memory tradeoffs.
Argon2 有一个主要变体:Argon2id,以及两个补充变体:Argon2d 和 Argon2i。Argon2d 使用依赖于数据的内存访问,这使其适用于加密货币和工作量证明应用程序,不会受到侧信道定时攻击的威胁。Argon2i 使用与数据无关的内存访问,这是密码散列和基于密码的密钥派生的首选。Argon2id 在内存上的第一次迭代的前半部分作为 Argon2i 工作,在其余部分作为 Argon2d 工作,因此由于时间-内存权衡,提供了侧信道攻击保护和蛮力成本节约。
Argon2i support was added in PHP 7.2, and you request it like this:
在 PHP 7.2 中添加了 Argon2i 支持,您可以像这样请求它:
$hash = password_hash('mypassword', PASSWORD_ARGON2I);
and Argon2id support was added in PHP 7.3:
PHP 7.3 中添加了 Argon2id 支持:
$hash = password_hash('mypassword', PASSWORD_ARGON2ID);
No changes are required for verifying passwords since the resulting hash string contains information about what algorithm, salt, and work factors were used when it was created.
验证密码不需要更改,因为生成的哈希字符串包含有关创建时使用的算法、盐和工作因素的信息。
Quite separately (and somewhat redundantly), libsodium (added in PHP 7.2) also provides Argon2 hashing via the sodium_crypto_pwhash_str ()
and sodium_crypto_pwhash_str_verify()
functions, which work much the same way as the PHP built-ins. One possible reason for using these is that PHP may sometimes be compiled without libargon2, which makes the Argon2 algorithms unavailable to the password_hash function; PHP 7.2 and higher should always have libsodium enabled, but it may not - but at least there are two ways you can get at that algorithm. Here's how you can create an Argon2id hash with libsodium (even in PHP 7.2, which otherwise lacks Argon2id support)):
libsodium(在 PHP 7.2 中添加)非常独立(并且有些冗余)还通过sodium_crypto_pwhash_str ()
和sodium_crypto_pwhash_str_verify()
函数提供 Argon2 散列,其工作方式与 PHP 内置程序非常相似。使用这些的一个可能原因是 PHP 有时可能在没有 libargon2 的情况下编译,这使得 password_hash 函数无法使用 Argon2 算法;PHP 7.2 及更高版本应该始终启用 libsodium,但可能不会 - 但至少有两种方法可以获得该算法。以下是使用 libsodium 创建 Argon2id 哈希的方法(即使在 PHP 7.2 中,否则缺少 Argon2id 支持):
$hash = sodium_crypto_pwhash_str(
'mypassword',
SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
);
Note that it doesn't allow you to specify a salt manually; this is part of libsodium's ethos – don't allow users to set params to values that might compromise security– for example there is nothing preventing you from passing an empty salt string to PHP's password_hash
function; libsodium doesn't let you do anything so silly!
请注意,它不允许您手动指定盐;这是 libsodium 精神的一部分——不允许用户将参数设置为可能危及安全的值——例如,没有什么可以阻止您将空盐字符串传递给 PHP 的password_hash
函数;libsodium 不会让你做任何愚蠢的事情!
回答by Shemeer M Ali
回答by Nayab Muhammad
As we all know storing password in clear text in database is not secure. the bcrypt is a hashing password technique.It is used to built password security. one of the amazing function of bcrypt is it save us from hackers it is used to protect the password from hacking attacks because the password is stored in bcrypted form.
众所周知,在数据库中以明文形式存储密码是不安全的。bcrypt 是一种散列密码技术。它用于构建密码安全性。bcrypt 的惊人功能之一是它使我们免受黑客攻击 它用于保护密码免受黑客攻击,因为密码以 bcrypted 形式存储。
the password_hash() function is used to create a new password hash. It uses a strong & robust hashing algorithm.The password_hash() function is very much compatible with the crypt() function. Therefore, password hashes created by crypt() may be used with password_hash() and vice-versa. The functions password_verify() and password_hash() just the wrappers around the function crypt(), and they make it much easier to use it accurately.
password_hash() 函数用于创建新的密码哈希。它使用强大且稳健的散列算法。password_hash() 函数与 crypt() 函数非常兼容。因此,由 crypt() 创建的密码哈希可以与 password_hash() 一起使用,反之亦然。函数 password_verify() 和 password_hash() 只是函数 crypt() 的包装器,它们使准确使用它变得更加容易。
SYNTAX
句法
string password_hash($password , $algo , $options)
string password_hash($password , $algo , $options)
The following algorithms are currently supported by password_hash() function:
password_hash() 函数目前支持以下算法:
PASSWORD_DEFAULT PASSWORD_BCRYPT PASSWORD_ARGON2I PASSWORD_ARGON2ID
PASSWORD_DEFAULT PASSWORD_BCRYPT PASSWORD_ARGON2I PASSWORD_ARGON2ID
Parameters: This function accepts three parameters as mentioned above and described below:
参数:该函数接受上面提到和下面描述的三个参数:
password: It stores the password of the user. algo: It is the password algorithm constant that is used continuously while denoting the algorithm which is to be used when the hashing of password takes place. options: It is an associative array, which contains the options. If this is removed and doesn't include, a random salt is going to be used, and the utilization of a default cost will happen. ReturnValue: It returns the hashed password on success or False on failure.
password:它存储用户的密码。 algo:它是密码算法常量,它是连续使用的,同时表示在进行密码散列时要使用的算法。 options:它是一个关联数组,其中包含选项。如果将其删除且不包括在内,将使用随机盐,并且将使用默认成本。 返回值:成功时返回散列密码,失败时返回 False。
Example:
示例:
Input : echo password_hash("GFG@123", PASSWORD_DEFAULT); Output : $2y$10$.vGA19Jh8YrwSJFDodbfoHJIOFH)DfhuofGv3Fykk1a
Input : echo password_hash("GFG@123", PASSWORD_DEFAULT); Output : $2y$10$.vGA19Jh8YrwSJFDodbfoHJIOFH)DfhuofGv3Fykk1a
Below programs illustrate the password_hash() function in PHP:
下面的程序说明了 PHP 中的 password_hash() 函数:
<?php echo password_hash("GFG@123", PASSWORD_DEFAULT); ?>
<?php echo password_hash("GFG@123", PASSWORD_DEFAULT); ?>
OUTPUT
输出
$2y$10$Z166W1fBdsLcXPVQVfPw/uRq1ueWMA6sLt9bmdUFz9AmOGLdM393G
$2y$10$Z166W1fBdsLcXPVQVfPw/uRq1ueWMA6sLt9bmdUFz9AmOGLdM393G