1

I've used the following instructions to install a mail server: http://www.geoffstratton.com/ubuntu-mail-server-postfix-dovecot-and-mysql

Now I'm trying to program a login form in PHP but don't know how to compare the entered password with the saved password.

This is the mysql-code for the password encryption:

ENCRYPT('PASSWORD', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16)))

I don't understand how it works because with every call of this function a completely new string is being generated.

This is what I have so far:

crypt($_POST[‘password’], '$6$'.substr(sha1(rand()), 0, 16))

But as I said every time I get a new string.

aygul
  • 3,227
  • 12
  • 38
  • 42
B. Reiter
  • 13
  • 5
  • Possible duplicate of [PHP & MySQL compare password](http://stackoverflow.com/questions/488804/php-mysql-compare-password) – jwpfox Sep 02 '16 at 22:37
  • For PHP use password_hash and password-verify, see the following for why: Just using a hash function is not sufficient and just adding a salt does little to improve the security. Instead iIterate over an HMAC with a random salt for about a 100ms duration and save the salt with the hash. Use functions such as PBKDF2, password_hash, Bcrypt and similar functions. The point is to make the attacker spend a lot of time finding passwords by brute force. – zaph Sep 03 '16 at 16:13

2 Answers2

1

Use the PHP functions password_hash and password_verify. These functions salt and iterate to provide secure protection.

See PHP Manual password_hash and password-verify.

string password_hash ( string $password , integer $algo [, array $options ] )

Returns the hashed password, or FALSE on failure.

boolean password_verify ( string $password , string $hash )

Returns TRUE if the password and hash match, or FALSE otherwise.

Example code:

$hash = password_hash("rasmuslerdorf", PASSWORD_DEFAULT)

if (password_verify('rasmuslerdorf', $hash)) {
    echo 'Password is valid!';
} else {
    echo 'Invalid password.';
}

In your case you grab the password hash for that username from the database, and keep it in a variable called $hash. Then you use password_verify() like this:

password_verify($_POST["password"], $hash)

zaph
  • 111,848
  • 21
  • 189
  • 228
  • Thanks so much for your answer! It works with password_verify. But if I encrypt my passwords with password_hash and add it to my database, dovecot can't use them. But with the encryption from the mail-tutorial and password_verify it works wonderful! – B. Reiter Sep 03 '16 at 20:15
0

Consider the case where a password is simply stored as its hash. Anyone reading the data would have a hard job working out what the password actually is, however its not impossible, indeed there are online database containg vast numbers of indexed hashes and the corresponding cleartext - its possible to simply lookup the hash for commonly chosen passwords. Further, consider the case if two users had the same hash - that also means anyone reading the data would know they had the same password.

Both these problems are addressed on secure system by adding a random string, known as a salt to the cleartext. This salt is only generated once and is then stored alongside the password.

So the data you have stored is $6$[salt]$[hash of (salt + password)]

To verify the password you recreate the hash using the stored salt and the password presented and compare that with stored hash. The crypt function ignores any data after the salt, so you simply do this:

if ($stored === crypt($_REQUEST['password'], $stored)) {
    // Password is valid

The code you are using has very low entropy in its salt derivation - this is probably adequate for most purposes but not in highly secure contexts.

symcbean
  • 47,736
  • 6
  • 59
  • 94