Why is the PHP crypt() function returning the same thing for two different strings?

mysql, password-protection, php

Solution

The standard DES-based `crypt()` [...] only uses the first eight characters of `str`, so longer strings that start with the same eight characters will generate the same result (when the same salt is used).

source

Use a salt that starts with `$<algo>$` to use something other than DES. See the `crypt()` documentation for details.

Problem

I'm using PHP's `crypt` function for password hashing/encryption, but I don't think I am doing it right because "nathan12" and "nathan123" both allow me to login to my account on my system (the actual password is "nathan123", and therefore "nathan12" or anything else should NOT allow me to login). Here's what my system does when a user registers: ``` [...] $salt = uniqid(mt_rand(), true); $password = crypt($password, $salt); // '$password' is the inputted password $insertUserStmt = $mysqli->prepare("INSERT INTO users (name, username, password, password_salt, email, created) VALUES (?, ?, ?, ?, ?, ?)"); $insertUserStmt->bind_param("sssssi", $name, $username, $password, $salt, $email, time()); $insertUserStmt->execute(); [...] ``` It inserts the hashed/encrypted password (`$password`) into the database along with the `$salt`. When someone tries to login, the following is done to check if the user has inputted the correct password for the username they inputted: ``` [...] // $password_salt is from DB; $password is inputted password $password_crypt = crypt($password, $password_salt); // $login_password is from DB if($password_crypt == $login_password) { [...] ``` I'm probably not even using the `crypt` function properly, but according to the PHP docs the first parameter is a string (the password) and second is the salt.

Original source