简体   繁体   English

哈希密码注册/登录

[英]Hashed password register / login

I'v googled around for way to do this properly and there's just a lot of variations on how to do so. 我在谷歌周围寻找正确执行此操作的方法,并且操作方法有很多变体。 So i've come up with this and wouldn't mind some critique and links to better practices. 所以我想出了这一点,不介意一些批评和与更好做法的链接。

// Register Form - User providese username(email) password(text) // //注册表格-用户提供用户名(电子邮件)密码(文本)//

So i grab the data: 所以我抓到数据:

$user = mysql_real_escape_string($_POST['user']);
$pswd = mysql_real_escape_string($_POST['pass']);
$salt = hash( 'sha256', microtime() . rand() );
$encrypt = hash( 'sha256', $pswd . $salt );

Then insert into database user_email | 然后插入数据库user_email | encrypted_pass | crypto_pass | salt

// Login Form - User providese username(email) password(text) // //登录表单-用户提供用户名(电子邮件)密码(文本)//

So first based on user(email) i grab encrypted_pass and salt info. 因此,首先基于用户(电子邮件),我获取了crypto_pass和salt信息。 Then, 然后,

$user = mysql_real_escape_string($_POST['user']);
$pswd = mysql_real_escape_string($_POST['pass']);

$encrypted_pass_fromDB = $var['encrypted_pass'];
$salt_fromDB = $var['salt'];

if (hash( 'sha256', $passwrd . $salt_fromDB) === $encrypted_pass_fromDB)
     {
      echo "GOT IT!";
     }

I've read bcrypt is a better option, but for now i want to understand the SALT method better. 我读过bcrypt是更好的选择,但现在我想更好地了解SALT方法。 Also, when i use $options = ['cost' => 11,]; 另外,当我使用$ options = ['cost'=> 11,]时; i get an error Parse error: syntax error, unexpected '[' but that's a separate issue i guess. 我收到一个错误解析错误:语法错误,意外的'[',但是我想那是一个单独的问题。 Used code based on PHP salt and hash SHA256 for login password 使用基于PHP salt和哈希SHA256的代码作为登录密码

Any comments are appreciated! 任何意见表示赞赏! Thanks! 谢谢!

The only thing that you are protected against when adding a salt to your hash is the use of huge tables of pre-computed hashes called "Rainbow Tables". 在向哈希表中添加盐时,唯一要防止的事情就是使用称为“彩虹表”的预计算哈希表。 These have not been a major problem in quite some time, though because: 尽管由于以下原因,这些在相当长的时间内并不是主要问题:

  1. Rainbow tables containing extended character sets are massive , some requiring upwards of 16GB of RAM to search. 包含扩展字符集的Rainbow表非常庞大 ,有些需要超过16GB的RAM才能进行搜索。
  2. Parallelized bruteforce cracking across multiple computers, or offloaded to cloud services like AWS are faster, cheaper, and makes the addition of simple salts virtually inconsequential. 跨多台计算机的并行蛮力破解或卸载到AWS之类的云服务更快,更便宜,并且使添加简单的盐实际上变得无关紧要。

Better algorithms hash the password thousands of times and apply the given salt in a cryptographically "proper" way to make it more difficult to crack. 更好的算法会对密码进行数千次哈希处理,然后以加密的“正确”方式应用给定的盐,使其更难以破解。 However, the hashing algorithms that they are based on like SHA and MD5 are designed to be small and fast, and bruteforcing them requires large amounts of CPU time, which is cheap and easy to parallelize. 但是,它们所基于的哈希算法(例如SHA和MD5)被设计为小型且快速的,对它们执行强行处理需要大量的CPU时间,这很便宜且易于并行化。

Bcrypt is different. Bcrypt是不同的。 It uses the Blowfish algorithm which requires relatively large amounts of RAM, which is expensive, and thus difficult to parallelize. 它使用Blowfish算法,该算法需要相对大量的RAM,这很昂贵,因此很难并行化。 This is why everyone recommends it so strongly. 这就是为什么每个人都强烈推荐它的原因。

TL;DR Hashing is better than plaintext, salted is better than unsalted, bcrypt is miles better than pretty much everything else out there so frickin use it . TL; DR哈希比纯文本好,加盐比未加盐更好,bcrypt比其他所有东西都好得多,因此frickin可以使用它

You should use the built in crypt function: 您应该使用内置的crypt函数:

http://php.net/crypt http://php.net/crypt

You have two options: 您有两种选择:

Let PHP Crypt generate the salt 让PHP地穴产生的盐

$user = mysql_real_escape_string($_POST['user']);
$pswd = mysql_real_escape_string($_POST['pass']);

//Salt is generated automatically
$encrypt = crypt( $pswd );

Generate the Salt yourself 自己产生盐

$user = mysql_real_escape_string($_POST['user']);
$pswd = mysql_real_escape_string($_POST['pass']);

//These are the settings for the salt (Separated so you can understand it)
$algorithm = "2a";
$length = "12";

//Start the salt by specifying the algorithm and length
$salt = "$" . $algorithm . "$" . $length . "$";

//Add on random salt and make base64 adjusted for bcrypt's version
$salt .= substr( str_replace( "+", ".", base64_encode( mcrypt_create_iv( 128, MCRYPT_DEV_URANDOM ) ) ), 0, 22 );

//Encrypt with your generated salt
$encrypt = crypt( $pswd, $salt );

Verifying it is easy: 验证很容易:

if ( $encrypted_pass_fromDB_with_salt === crypt( $passwrd, $encrypted_pass_fromDB_with_salt ) ) echo "ok";

PHP offers now such an easy way to generate safe password hashes, that we should use it, have a look at the function password_hash() . PHP现在提供了一种生成安全密码哈希的简单方法,我们应该使用它,看看函数password_hash()

// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);

// 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);

Of course it is good to understand how a salt works (and how difficult it is to handle it correctly), so try it out but use the function above for your life system. 当然,了解盐的工作原理(以及正确处理盐的难度)是一件好事,因此请尝试一下,但是将上述功能用于您的生命系统。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM