我不时听到"使用bcrypt在PHP中存储密码,bcrypt规则"的建议.
但是什么bcrypt
呢?PHP没有提供任何此类功能,维基百科关于文件加密实用程序的唠叨和Web搜索只是揭示了不同语言的Blowfish的一些实现.现在Blowfish也可以通过PHP获得mcrypt
,但是如何帮助存储密码?Blowfish是一种通用密码,它有两种工作方式.如果它可以加密,则可以解密.密码需要单向散列函数.
解释是什么?
上周我读了很多关于密码哈希和Blowfish的文章,似乎是(现在)最好的哈希算法之一 - 但这不是这个问题的主题!
Blowfish只考虑输入密码中的前72个字符:
<?php
$password = "Wow. This is a super secret and super, super long password. Let's add some special ch4r4ct3rs a#d everything is fine :)";
$hash = password_hash($password, PASSWORD_BCRYPT);
var_dump($password);
$input = substr($password, 0, 72);
var_dump($input);
var_dump(password_verify($input, $hash));
?>
Run Code Online (Sandbox Code Playgroud)
输出是:
string(119) "Wow. This is a super secret and super, super long password. Let's add some special ch4r4ct3rs a#d everything is fine :)"
string(72) "Wow. This is a super secret and super, super long password. Let's add …
Run Code Online (Sandbox Code Playgroud) 我修改了我的旧帖子.我尝试了crypt()函数,现在尝试使用password_hash()和password_verify()来验证来自数据库的加密密码,但在每次调用时,password_hash()函数返回不同的加密字符串,而password_verify()无法匹配.
这就是我这样做的方式.
//please ignore the syntax error if any
$data = '11';
$dbpass = password_hash($data, PASSWORD_BCRYPT);
echo $dbpass; // displays the random strings on each page refresh.
Run Code Online (Sandbox Code Playgroud)
一旦密码保存到数据库中,在登录过程中就不会匹配.以下是我的实际功能.
private function process_data($password){
$password = __STR.$password.__STR;
return password_hash($password, PASSWORD_BCRYPT);
}
private function processed($login_password, $dbpassword){
$login_password = __STR.$login_password.__STR;
return password_verify($login_password, $dbpassword);
}
Run Code Online (Sandbox Code Playgroud)
在为密码创建散列字符串的每个函数调用中,该函数下次返回不同的字符串.
我正在考虑使用password_hash()函数来加密用户密码.我知道如果你没有提供它,这个函数会默认生成salt,甚至鼓励使用默认的salt而不是你自己的salt.我目前正在权衡3个选项,无法决定使用哪个,所以如果你能帮助我,我会很感激.
1.选项:password_hash(),默认为salt
$passwordInput = $_POST['password'];
$passwordHash = password_hash($passwordInput, PASSWORD_BCRYPT);
//INSERT $passwordHash INTO DATABASE
Run Code Online (Sandbox Code Playgroud)
2.选项:带自定义盐的password_hash()
$options = ['salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM)];
$passwordInput = $_POST['password'];
$passwordHash = password_hash($passwordInput, PASSWORD_BCRYPT, $options);
//INSERT $passwordHash INTO DATABASE
Run Code Online (Sandbox Code Playgroud)
3.选项:根本不使用password_hash()
我将此选项基于2014年的帖子:基于表单的网站身份验证的权威指南.基本上如果它是一个比password_hash()更安全的方法,我会使用这样的东西:
$salt = uniqid(rand(0, 1000000);
$passwordInput = $_POST['password'];
$password = hash('sha512', $salt . $passwordInput);
//INSERT $password AND $salt INTO DATABASE SEPARATELY
Run Code Online (Sandbox Code Playgroud) 我的问题来自于 如何使用河豚散列长密码(> 72个字符)
我使用bcrypt(河豚)来哈希密码.所以,正如我从这个问题中发现的那样 https://security.stackexchange.com/questions/39849/does-bcrypt-have-a-maximum-password-length
它的字符数限制为72.
所以,我开始考虑限制密码的最大长度,但是在这些问题及其答案之后
所有人都说是反对的.提到的东西,比如
a maximum length specified on a password field should be read as a SECURITY WARNING
通过这个答案 - /sf/answers/6980711/所以,我认为我不符合其中一个案例.当然,我同意愚蠢的限制,例如最大长度10,甚至更糟,8或6,但不是30,40或更长的密码(盐渍)被认为是安全的?从这篇文章(虽然有点旧),但它说
it can make only 71,000 guesses against Bcrypt per second
Run Code Online (Sandbox Code Playgroud)
这适用于8个字符的密码.因此,我想象自定义彩虹表会蛮力一个30个或更多字符密码(考虑到每个密码都有自己的盐),因为彩虹表大小呈指数增长
引用同一篇文章的评论
每次在密码中添加一个字符时,都会以指数方式增加通过暴力破解所需的难度.例如,8-char密码的密钥空间为95 ^ 8组合,而20-char密码的密钥空间为95 ^ 20组合.
因此,对于一个20长度密码与bcrypt根据那将是必要95 ^ 20 /(71 000*3600*24*365)~10年28度(如果我做对了)
qsn1:现在,在这种情况下,使用blowfish有一个意思是不要将密码最大长度限制为72,因为在任何情况下都会被截断,因此这里没有额外的安全性增益.
qsn2:即使存在salt(每个用户都是唯一的并保存在db中),毕竟我想在密码中添加pepper(在应用程序中硬编码而不是保存在db中).我知道是否会增加一些额外的安全性,但我认为以防万一db(或db backup)只是泄露,胡椒将是有用的.
https://security.stackexchange.com/a/3289/38200
所以,为了能够添加20个字符胡椒,我需要将密码最大长度设置为50左右.我想这样:让我们说用户是使用70个字符,在大多数情况下(如果不是全部),它将是一些短语或类似的,而不是生成强大的字符,因此将用户限制为50最大长度并添加另一个20-22更安全字符胡椒肯定更安全/随机.另外,让我们说黑客正在使用"常用短语"的彩虹表,我认为有更高的机会,这72 character common phrase
将被黑客攻击,而不是50 character common phrase + 22 character …
encryption passwords password-policy password-storage password-encryption
在阅读了有关php中会话管理的一些主题之后,我开始进行这个安全性讨论,看看:https: //paragonie.com/blog/2015/04/secure-authentication-php-with-long-term-persistence#title. 2
引用章节:胡椒还是胡椒?
一个更好的解决方案,在使用硬件分离时尤其有用,是在将哈希值插入数据库之前加密哈希值.有了这个安全措施,即使攻击者找到了转储所有数据库表的方法,他们首先必须解密哈希值才能开始破解它们.将PHP和数据库放在不同的硬件上,这会变得更加安全.
在本文中,共享https://github.com/defuse/php-encryption的链接...
到目前为止,我只使用password_hash()来将密码存储在数据库中.是否可以加密哈希本身?你怎么看?
谢谢你的想法!
我一直在寻找加密密码以供我的面板使用的最佳方法,我决定继续使用 BCRYPT,这仅仅是因为每次加密的成本以及它通常被认为是目前最好的加密方法之一。当前时间。
我使用的是双向盐,因此每个用户都有一个独特的盐,然后显然是存储在我的应用程序中的盐,我注意到一些相当奇怪的行为..根据 PHP 文档,这种行为是否正常?
无论如何,这是我使用的代码:
$Crypto = new Crypto;
echo $Crypto->encrypt( "123456789abcdefghijklm", "StackOverflow_Is_Awesome!" ); // First parameter being the "User Salt", second being the password.
// Above outputs $2y$13$123456789abcdefghijkleepFY8JLvsf2YbnWolqQyO3DIzrCeNIu
Run Code Online (Sandbox Code Playgroud)
现在,加密类:
<?php
// ASSUMING $this->hashingSalt = HBSNi3y7ruhbVGkhdg83ijdbvghiojkgudL;JP
class Crypto {
private $hashingSalt, $database;
public function __construct( $salt )
{
$this->hashingSalt = $salt;
$this->database = new DatabaseFunctions();
}
public function encrypt( $salt, $password )
{
$options = array(
'cost' => 13,
'salt' => $salt //22 chars
);
return password_hash( $password . …
Run Code Online (Sandbox Code Playgroud) passwords ×6
php ×6
security ×3
bcrypt ×2
encryption ×2
hash ×2
blowfish ×1
cryptography ×1
mysql ×1
salt ×1