Welcome Guest, Not a member yet? Register   Sign In
Using the PASSWORD() function
#1

I am rebuilding an existing site in CodeIgniter which someone previously built in bespoke php which is largely full of depricated functionality hence the rebuild. This is my first CodeIgniter project but it seemed a good framework and fitted the requirement well.

My issue is, I don't have much flexibility on the existing database structure as it is full of 1000's of records of data. The issue I am facing is with the members section, the members have their credentials stored and the password is hashed using the mysql function PASSWORD(). I need to keep it that way other wise they'll have issues when logging in.

I tried to use the function in my data array for registering new accounts like so but it failed:

'lc_user' => PASSWORD($this->input->post('jbsEmail')),

I found a similar way to do it which was (not worried about sanitising the post data at this stage):

$hashedPassword = password_hash($this->input->post('jbsPassword'), PASSWORD_DEFAULT);
'lc_password' => $hashedPassword,

The trouble is here is php hashes the password so it will not be stored as the existing passwords, so when people go to log in I need to do something like:

WHERE password=PASSWORD($potsPassword), so based on that kind of scenario I think I need to be able to use PASSWORD() when running queries, I have not found a solution yet to be able to do this with CodeIgniter, can anyone suggest a solution?
Reply
#2

(This post was last modified: 03-28-2018, 02:31 PM by jreklund. Edit Reason: Formatting )

1. Add "passwordConverted" in the database, default into 0.
2. Select user from database based on username/email
2. Check if "passwordConverted" are 0 or 1

If 0:
1. Make a query with the password, if it's matches login user
2. Rehash password and replace password in DB.
3. Set "passwordConverted" into 1 in DB.

If 1:
1. Validate with password_verify, if it's matches login user.

According to Google, MySQL password() function are equal too:
PHP Code:
function mysql_password($string){
    
$pass strtoupper(
            
sha1(
                    
sha1($stringtrue)
            )
    );
    
$pass '*' $pass;
    return 
$pass;


If that's correct, you can do passwordConverted = 0:
1. If it's a match with mysql_password; login user
2. Rehash password and replace password in DB.
3. Set "passwordConverted" into 1 in DB.
Reply
#3

(03-28-2018, 02:24 PM)jreklund Wrote: 1. Add "passwordConverted" in the database, default into 0.
2. Select user from database based on username/email
2. Check if "passwordConverted" are 0 or 1

If 0:
1. Make a query with the password, if it's matches login user
2. Rehash password and replace password in DB.
3. Set "passwordConverted" into 1 in DB.

If 1:
1. Validate with password_verify, if it's matches login user.

According to Google, MySQL password() function are equal too:
PHP Code:
function mysql_password($string){
 
   $pass strtoupper(
 
           sha1(
 
                   sha1($stringtrue)
 
           )
 
   );
 
   $pass '*' $pass;
 
   return $pass;


If that's correct, you can do passwordConverted = 0:
1. If it's a match with mysql_password; login user
2. Rehash password and replace password in DB.
3. Set "passwordConverted" into 1 in DB.

You know what? That is exactly why I posted this, that solution sounds perfect, it's funny how the obvious is often not apparent until somebody points it out to you, nice one that's great and that's exactly what I shall do. That is a great response and now I can crack on with the build, thanks a lot man Smile
Reply
#4

(This post was last modified: 04-09-2018, 01:03 PM by jreklund. Edit Reason: Code example are wrong )

Hi again, I just thought about something. There are a more recommended way, as your passwords can be matched against a rainbow table.
If you can use the provided mysql_password function please do the following instead.

1. Take every users password and rehash them using password_hash and then place a passwordConverted = 0 in the database.
What I mean is create a one time php file. Make a loop and get every users "mysql password" and add it into password_hash("MYSQL_PASSWORD",PASSWORD_DEFAULT) and replace the one in the database. Now you have a double hash password that can't be matched against a rainbow table. So if two or more users have 'password' they will be completely different.

Now if a user logins and passwordConverted are 0:
1. Validate password using:
PHP Code:
password_verify(
    
mysql_password(
        
$this->input->post('password')
    ),
    
$dbPassword
); 
2. Rehash password password_hash($this->input->post('password'),PASSWORD_DEFAULT);
3. Save new password hash and passwordConverted = 1 in DB.

If 1:
1. password_verify($this->input->post('password'),$dbPassword);

Now you are secure. :-)
Reply
#5

Just one issue I'm facing is each time I has the $_POST['password'] a new hash is generated rather then the same one, so when I attempt to match it in the database it will always return false, am I missing something?
Reply
#6

(This post was last modified: 04-09-2018, 01:08 PM by jreklund.)

Which one of the code examples do you have a problem with? I made a coding error in the last post, so I have fixed it.

password_hash always generate a unique hash, but will match with password_verify.
You need to put the password ($_POST) from the user directly inside password_verify. And you need to retrieve the password from the database to be used inside password_verify. You can't match a password with SQL.

PHP Code:
$hash '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq';

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


All of these will validate against the word 'password'.
Code:
$2y$10$QIuNcD/a//Z.6D0iDzJe9eeN5BtjOfgqwdqKRLB8t15AFVbl9POOu
$2y$10$oWPQL.4mg0XK/9EFjYBATO6hb4edzIfUrAA3Zirqu4tv96kGHvvt2
$2y$10$zkwuzkFJbii42QZjVpfUw.sKqZVAsXfCExW2liMlvb3guB.JsUxTu
$2y$10$GeTvYtMFLq4mB3eaIlz8Pev/pcLqHD1RLoCuy/3r4I0beBzKNT0hG
$2y$10$LOKzF8Ox8yUS9PcDLF3s1OLCzPiM0419znNugPslj8V/yqx1m.NcS
$2y$10$1ofeXPiqPnajZ15fNQLTY.kt66uTemd78z8cp1rMUEHCG7BxK3ecK
$2y$10$ZM0XTjOHkqGFroILJvs1TeKG39P5furPkB.7S940YoTfAsUwPq0sq
$2y$10$cIpKaqhunEE/2oGtowK32O74snnTxXw0AtAlkr0sDJfB20.VI.Ftu
$2y$10$cNjQaFfRKHeC/2q4P9cLouSsWjHEA5NxAy9W8N65r0A9ATKBmcHhe
$2y$10$709VYoupwK/vX2yhOvD/leTzfSYgJrFcXPgkE1bhYTD5RozrmpsrW
Reply
#7

Thanks that makes sense although I've not quite managed to strike a match with it, here is my example:

$hash password_hash($this->input->post('jbsPassword'), PASSWORD_DEFAULT);

if (
password_verify('$data['userData']['lc_password']'$hash)) {
    echo 
'Password is valid!';
} else {
    echo 
'Invalid password.';
}


The value of $data['userData']['lc_password'] was returning as:
*D426965E1031A24EC5DF16CD0DFE52E9407E4203

So then I tried to wrap the password from the database in to the password hash function like:

if (password_verify($this->hashPassword($data['userData']['lc_password']), $jbsPassword)) {

But that returns false too, the value of $this->hashPassword($data['userData']['lc_password'] is:
$2y$10$juxQdvYcKBf80AP.p3jCBOpESFYWG382X32VZZx4HHwKArN1A2kQe


So the last example I printed out the two vars, first from the database and then from the post data and I get:
Invalid password:

Arg one: $2y$10$juxQdvYcKBf80AP.p3jCBOpESFYWG382X32VZZx4HHwKArN1A2kQe
Arg two: $2y$10$w9fnaN4JY6LiwrXVrIN18.mbROYkJeiTGh5z9FqCEA9zxliRDquxK

my password_hash function:


public function hashPassword($password)

{

  return password_hash($password, PASSWORD_DEFAULT);
}

Does anything here look wrong?
Reply
#8

Hi, it's supposed to be like this. And only after you have successfully converted everyone's password with password_hash.
passwordConverted = 1;
PHP Code:
if (password_verify($this->input->post('jbsPassword'), $data['userData']['lc_password'])) {
 
   echo 'Password is valid!';
} else {
 
   echo 'Invalid password.';


Validate passwords as of now:
passwordConverted = 0;
PHP Code:
function mysql_password($string){
 
   $pass strtoupper(
 
           sha1(
 
                   sha1($stringtrue)
 
           )
 
   );
 
   $pass '*' $pass;
 
   return $pass;
}

if (
mysql_password($this->input->post('jbsPassword') === $data['userData']['lc_password']) {
 
   echo 'Password is valid!';
 
   echo 'Convert password now!';
 
   $newPassword password_hash($this->input->post('jbsPassword'),PASSWORD_DEFAULT);
 
   // Save in DB
} else {
 
   echo 'Invalid password.';



If you rehash every password in the database:
passwordConverted = 0 AND password_hash have been looped thru on ALL passwords already.

PHP Code:
function mysql_password($string){
 
   $pass strtoupper(
 
           sha1(
 
                   sha1($stringtrue)
 
           )
 
   );
 
   $pass '*' $pass;
 
   return $pass;
}

if (
password_verify(mysql_password($this->input->post('jbsPassword')), $data['userData']['lc_password'])) {
 
   echo 'Password is valid!';
 
   echo 'Convert password now!';
 
   $newPassword password_hash($this->input->post('jbsPassword'),PASSWORD_DEFAULT);
 
   // Save in DB
} else {
 
   echo 'Invalid password.';

Reply




Theme © iAndrew 2016 - Forum software by © MyBB