Search code examples
phpencryptionauthenticationregistration

How to login to an existing user account with an encrypted (blowfish) password


I followed a tutorial on youtube on how to encrypt users password using the encrypt blowfish function. I have implemented it properly into my registration script, with it successfully registering an account and sending the encrypted password to the database. My issue though, is retrieving that encrypted password when trying to log a user in. When I try and login to an existing user, it gets down to that last else statement saying it doesn't exist, meaning the hashed password isn't being recognized.

Code for encrypt password function:

public function encryptPass($password, $rounds = 11)
        {
            $salt = "";
            // creates array of capital letters A-Z & lowercase as well as #'s 0-9
            $saltChars = array_merge(range('A', 'Z'), range('a', 'z'), range(0,9));

            for($i = 0; $i < 22; $i++)
            {
                // randomize the array
                $salt .= $saltChars[array_rand($saltChars)];
            }

            return crypt($password, sprintf('$2y$%02d$', $rounds) . $salt);

        }

Code used to register an account:

/// REGISTER ACCOUNT ///
if(isset($_POST['register']))
{
    // clean up the fields
    $username = mysql_real_escape_string(trim($_POST['username']));
    $emailid = mysql_real_escape_string(trim($_POST['emailid']));
    $password = mysql_real_escape_string(trim($_POST['password']));
    $confirmPassword = mysql_real_escape_string(trim($_POST['confirm_password']));
    if($password == $confirmPassword)
    {

        $iUe = $dbMan->ifUsernameExist($username);
        $iEe = $dbMan->ifEmailExist($emailid);

        // if username and email don't already exist, continue with registration
        if(!$iUe && !$iEe)
        {

            // encrypt the users password
            $hashedPassword = $dbMan->encryptPass($password);
            echo "$password <br> \n";

            // register the account
            $register = $dbMan->UserRegister($username, $emailid, $hashedPassword);

            // if registration was succesful
            if($register)
            {
                 echo "<script>alert('Registration Successful')</script>";
            }
            else
            {
                echo "<script>alert('Registration Not Successful')</script>";
            }
        } 
        else 
        {
            echo "<script>alert(' That email or username already exists! ')</script>";
        }
    } 
    else 
    {
        echo "<script>alert(' Passwords do not match! ')</script>";

    }


}

Code used for the login:

/// LOGIN ACCOUNT /// 
if(isset($_POST['login']))
{   
    // 'convert' post variables to session variables
    $_SESSION['username'] = $_POST['username'];
    $_SESSION['password'] = $_POST['password'];

    // clean em up, get rid of any white spaces or sql injection special chars
    $username = mysql_real_escape_string(trim($_SESSION['username']));
    $password = mysql_real_escape_string($dbMan->encryptPass(trim($_SESSION['password'])));

    echo "$password<br>\n";

    $user = $dbMan->Login($username, $password);
    // if theres an acccount with that username/pw in the db
    if ($user) 
    {

        // login successful
        header("location:index.php");
    } 
    else 
    {
        // Registration Failed
        echo "<script>alert(' The email or password do not match! ')</script>";
    }
}

Code for dbManager:

<?php  

require_once 'dbConnect.php'; 
//session_start();


    class dbManager
    {   
        function __construct() 
        {  
            // connecting to database  
            $db = new dbConnect();  

        }  
        // destructor  
        function __destruct() 
        {  

        }

        public function UserRegister($username, $emailid, $password)
        {  
            $query = mysql_query("INSERT INTO users(username, emailid, password) values('".$username."','".$emailid."','".$password."')") or die(mysql_error());  
            return $query;  

        } 

        public function Login($username, $password)
        {  
            $query = mysql_query("SELECT * FROM users WHERE username = '".$username."' AND password = '".$password."'");  
            $user_data = mysql_fetch_array($query);  
            //print_r($user_data);  
            $num_rows = mysql_num_rows($query);  

            if ($num_rows == 1)   
            {  

                $_SESSION['login'] = true;  
                $_SESSION['uid'] = $user_data['id'];  
                $_SESSION['username'] = $user_data['username'];  
                $_SESSION['emailid'] = $user_data['emailid'];  

                return TRUE; 
            }  
            else  
            {  
                return FALSE;  
            }  


        }


        // check if username exists in db
        public function ifUsernameExist($username)
        {  
            $qr = mysql_query("SELECT * FROM users WHERE username = '".$username."'");  
            echo $row = mysql_num_rows($qr);  
            if($row > 0)
            {  
                return TRUE;
            } 
            else 
            {  
                return FALSE;  
            }  
        }

        // check if email exists in db
        public function ifEmailExist($emailid)
        {
            $qr = mysql_query("SELECT * FROM users WHERE emailid = '".$emailid."'");
            echo $row = mysql_num_rows($qr);
            if($row > 0)
            {
                return TRUE;    
            }
            else
            {
                return FALSE;
            }
        }

        // encrypt password 
        public function encryptPass($password, $rounds = 11)
        {
            $salt = "";
            // creates array of capital letters A-Z & lowercase as well as #'s 0-9
            $saltChars = array_merge(range('A', 'Z'), range('a', 'z'), range(0,9));

            for($i = 0; $i < 22; $i++)
            {
                // randomize the array
                $salt .= $saltChars[array_rand($saltChars)];
            }

            return crypt($password, sprintf('$2y$%02d$', $rounds) . $salt);

        }

    }  
?>  

Note: both the login and register 'methods' are in the same php file including the form markup. The encrypted function is located in a different file called dbManager.

Hopefully I provide enough information for someone to point me in the right direction. Any help is appreciated!

Thanks, Dev.


Solution

  • You need to pass your cleartext password to encrypt to compare it within the database.

    change

    $password = trim(mysql_real_escape_string($_SESSION['password']));
    

    to

    $password = $dbMan->encryptPass(trim(mysql_real_escape_string($_SESSION['password'])));
    

    In your login action.

    Ideally you would run the $dbMan->encryptPass before doing mysql_real_escape_string both on INSERTand SELECT.

    $password = mysql_real_escape_string($dbMan->encryptPass(trim($_SESSION['password'])));
    

    The salts have to be the same for encrypt and decrypt, seeing as you are using array_rand the salts are different on each pass. You have to store the salt someplace else. If you remove the salt or set it to a constant it will work now.