문제

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 | encrypted_pass | salt

// Login Form - User providese username(email) password(text) //

So first based on user(email) i grab encrypted_pass and salt info. 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. Also, when i use $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

Any comments are appreciated! Thanks!

도움이 되었습니까?

해결책 2

You should use the built in crypt function:

http://php.net/crypt

You have two options:

Let PHP Crypt generate the salt

$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";

다른 팁

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.
  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.

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.

Bcrypt is different. It uses the Blowfish algorithm which requires relatively large amounts of RAM, which is expensive, and thus difficult to parallelize. 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.

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().

// 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 ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top