Blowfish in CakePHP is generating different passwords everytime

谁说我不能喝 提交于 2019-11-30 09:33:23

问题


I'm having trouble implementing Blowfish Hashing in CakePHP. I've done it many times before but something really strange is happening this time.

When I do this in my Model:

<?php
    App::uses('BlowfishPasswordHasher', 'Controller/Component/Auth');
    class Person extends AppModel {
        public $hasAndBelongsToMany = 'Client';
        public $belongsTo = 'Role';
        public function beforeSave($options = array()) {
            if (!$this->id) {
                $passwordHasher = new BlowfishPasswordHasher();
                debug($passwordHasher->hash($this->data[$this->alias]['password']));
                debug($passwordHasher->hash($this->data[$this->alias]['password']));
                debug($passwordHasher->hash($this->data[$this->alias]['password']));
                debug($passwordHasher->hash($this->data[$this->alias]['password']));
                debug($passwordHasher->hash($this->data[$this->alias]['password']));
                debug($passwordHasher->hash($this->data[$this->alias]['password']));
                $this->data[$this->alias]['password'] = $passwordHasher->hash($this->data[$this->alias]['password']);
            }
            return true;
        }
    }

It outputs 6 different passwords:

/app/Model/Person.php (line 9)
'$2a$10$Ow67P5proa7LqBwlXCLFQOc/2WyfvSVNtBLNA5PMb2wxWuoK0mrvq'
/app/Model/Person.php (line 10)
'$2a$10$ZI5xv9SmLafBZOaikaIWY.jqyX68mS9RqvF4WbaxEuIj67ddKGguG'
/app/Model/Person.php (line 11)
'$2a$10$.5gRV3aQ8M/gDHVsSRmRpur8ugXjEidxPwTyuv5NVDUu3tHbCdmoC'
/app/Model/Person.php (line 12)
'$2a$10$58zHo0qAZSLa/KqTFvs6uOxjT0Ua1HlnGmQE5xpKf09in7Di9gCXa'
/app/Model/Person.php (line 13)
'$2a$10$MbHTtqgaCTfbK8JVO5Ad6.JKR3Zvipyv3yeid7Zb5MGx38.fufUCG'
/app/Model/Person.php (line 14)
'$2a$10$ya3gqRwR2osjAsS0jpuDcu/JNkKrvzZpy/Vsk4nBNY213JrwylDUa'

How is that even possible? What could I possibly be doing wrong?

For reference's sake, my components implementation looks like this but the issue occurs when I'm using scaffold as well:

<?php
    class PeopleController extends AppController {
        public $components = array(
            'Auth' => array(
                'loginAction' => array(
                    'controller' => 'people',
                    'action' => 'login'
                ),
                'authenticate' => array(
                    'Form' => array(
                        'fields' => array('username' => 'email'),
                        'userModel' => 'Person',
                        'passwordHasher' => 'Blowfish'
                    )
                )
            )
        );

Edit: Just to clarify, what I'm trying to get working here is the basic login functionality. My login action looks like this:

public function login() {

    if ($this->request->is('post')) {
        if ($this->Auth->login()) {
            return $this->redirect($this->Auth->redirectUrl());
        }
        else {
            $this->Session->setFlash(__('Username or password is incorrect'), 'default', array(), 'auth');
        }
    }
}

And my view looks like this:

<h2>Login</h2>
<?php echo $this->Session->flash('auth'); ?>
<?php echo $this->Form->create('Person', array('action' => 'login')); ?>
<?php echo $this->Form->input('email'); ?>
<?php echo $this->Form->input('password'); ?>
<?php echo $this->Form->end('Submit'); ?>

回答1:


This is expected behaviour. Blowfish hashes contain the randomly generated salt, the resulting hash, the number of rounds used to arrive at that resulting hash, and the method used for hashing. Let's break down your first example: Method: $2a Rounds: $10 Hash+Salt: $Ow67P5proa7LqBwlXCLFQOc/2WyfvSVNtBLNA5PMb2wxWuoK0mrvq

When authenticating, the hash string is split by the $ delimiter, and grabs the salt out of the final token. It's usually a fixed length from the end depending on the algorithm used(in this case it's probably /2WyfvSVNtBLNA5PMb2wxWuoK0mrvq). The steps to authenticate are then:

  1. Get plaintext
  2. For 2^$Rounds:
  3. Hash plaintext or result of previous round.
  4. Append the $Salt to the result

The hash is then $Method$Rounds$Result$Salt. Check the result against what is recorded in the database - if the output matches, the supplied plaintext is correct.




回答2:


Ultimately Security::_hash() is being used internally, which uses a pseudo random salt for use with crypt(), so that's the expected behavior, nothing wrong it.

https://github.com/cakephp/cakephp/blob/2.4.6/lib/Cake/Utility/Security.php#L276

Comparing passwords will work just fine, as it will use the salt of the stored password hash to generate a matching hash.




回答3:


maybe a posible reason if this will be for the Security.salt this should be empty or in the cakephp use the beforeFilter.

this in your appcontroller.php

public function beforeFilter() {
    Security::setHash('blowfish');
}

now in your PeopleController.php

public function beforeFilter() {
    parent::beforeFilter();
}

and in you model of People

public function beforeSave($options = array()) {
    // hash our password

    if (!$this->id) {
        $passwordHasher = new BlowfishPasswordHasher();
        $this->data[$this->alias]['password'] = $passwordHasher->hash($this->data[$this->alias]['password']);
    }


    return true;
}


来源:https://stackoverflow.com/questions/22667478/blowfish-in-cakephp-is-generating-different-passwords-everytime

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!