Simple PHP crypt() and MySQL implementation using SHA256

New PHP versions have some nice build-in cypt() features that you can use to securely store your users password to e.g mysql database. I am going to demonstrate and explain why you should encrypt passwords and how that can easily improve your sites basic security. I hope this helps you to better understand passwords, hashes and crypting.

Using PHP crypt() function

<?php
$userspassword = "ThisIsVeryHardPassword!123";
 
// Idea of salt is to make users password longer
// so that it's not vulnerable to attacks like http://en.wikipedia.org/wiki/Rainbow_table
 
$salt = "CrazyassLongSALTThatMakesYourUsersPasswordVeryLong123!!312567__asdSdas";
 
// Now users password will be = 
// CrazyassLongSALTThatMakesYourUsersPasswordVeryLong123!!312567__asdSdas + ThisIsVeryHardPassword!123
 
 
// Users password will now be combined (password+salt) to sha256 hash
$password = hash('sha256', $salt.$userspassword);
 
echo $password;
// output: fb5f7c18a269257d13fe0c409e5dc4f90c1fb9b6fa54996b58356591e0edd8ca
?>

If you want to add extra layer of security you can generate unique salt to each user and store that. Often it’s not really necessary in my opinion because as long as you use good long salt it will be enough to defend against rainbow tables. Just make sure that your users use enough complex password.

Salt is not really a secred and you don’t have to worry about it. Salt by itself wont open any passwords. It just adds more character to password making hash more complex against pre-hashed rainbow tables.

Authenticate crypted password with MySQL

First, the basic idea of crypting and storing password is that after user enters password it will never be plain text again. This means that when you check if password is a match you just compare stored hash with the hash you generate from user inputs. Picture below tries to explain same thing. If you are using unique salt for each user you must first retrive users salt from database and then generate hash and check if it’s a match.

Basic idea of veryfiying user with crypted password
Basic idea of veryfiying user with crypted password using php and mysql

Example code PHP MYSQL Using crypt() SHA256

<?php
  // Basic php MYSQL authentication with crypted password

  $username = $_POST['username'];
  $password = $_POST['password'];
  $salt = "CrazyassLongSALTThatMakesYourUsersPasswordVeryLong123!!312567__asdSdas";
  $password = hash('sha256', $salt.$password);
  //echo $password;
  
  // Mysql connection
  $mysqli = new mysqli("localhost","mysqluser","mysqlpassword","mysqldatabase");
  $stmt = $mysqli->prepare('SELECT userid FROM Users WHERE password = ? AND username = ?');
  // (ss -> string, string) Always bind parameters and use prepared statement to improve security
  $stmt->bind_param("ss", $password, $username);
  $stmt->execute();
  $stmt->bind_result($userid );

  if (!empty($stmt->fetch())) {
    // if fetch is not empty we have results and password hash was correct
    echo "User was found";
  } else
    echo "User was not found";

$mysqli->close();
?>

When you are testing, make sure that you have crypted password stored already in your database with same hash, otherwise it will never match. If you hashed password matches to the hash in MySQL database, user can login.

Conclusions

Sha256 is definetly better than using MD5 or storing passwords plain text. It adds extra layer of protection without hard work and there is not really difference between sha512 and sha256. If you want more secure way to encrypt your data you should use something like bcrypt. For more info about secure crypt methods you can read Bcrypt which is designed for this type of crypting and offers better protection for brute-force attacks. PHP supports Bcrypt

From Wikipedia about Bcrypt:

bcrypt is an adaptive function: over time, the iteration count can be increased to make it slower, so it remains resistant to brute-force search attacks even with increasing computation power.

But for now in my opinion sha256 is enough protection for average site and if you like you can increase rounds of hashing are performed to make it more complex. You can read more about it here.

Why use hash and encrypt password?

You should always store your users passwords in encrypted format because many users unfortunately use same password to their email and others services and if your sites database gets compromised and attacker get a hold of your database then all passwords are still crypted and you have more time to warn your users and ask then to change passwords. Also attacker can’t login to your service if he only have password hashes without cracking them because your database only contains hashes, not actual passwords.

And if the worst case scenario happens and you lose your database, you can still say that passwords are safely encrypted and it’s highly unlikely that attacker can to get them, so good PR for you in bad situation.

Jätä kommentti