CakePHP中的Blowfish每次都会生成不同的密码

时间:2014-03-26 16:34:46

标签: cakephp blowfish

我在CakePHP中实现Blowfish Hashing时遇到了麻烦。我以前做过很多次但是这次真的很奇怪。

当我在我的模型中执行此操作时:

<?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;
        }
    }

它输出6个不同的密码:

/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'

怎么可能呢?我怎么可能做错了?

为了参考,我的组件实现看起来像这样,但问题出现在我也使用scaffold时:

<?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'
                    )
                )
            )
        );

修改 只是为了澄清一下,我试图在这里工作的是基本的登录功能。我的登录操作如下所示:

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');
        }
    }
}

我的观点如下:

<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'); ?>

3 个答案:

答案 0 :(得分:3)

这是预期的行为。 Blowfish哈希包含随机生成的盐,生成的哈希值,用于获得结果哈希值的轮数以及用于散列的方法。让我们分解你的第一个例子: Method: $2a Rounds: $10 Hash+Salt: $Ow67P5proa7LqBwlXCLFQOc/2WyfvSVNtBLNA5PMb2wxWuoK0mrvq

进行身份验证时,哈希字符串由$ delimiter分割,并从最终令牌中获取盐。它通常是一个固定的长度,取决于使用的算法(在这种情况下,它可能是/2WyfvSVNtBLNA5PMb2wxWuoK0mrvq)。然后验证的步骤是:

  1. 获取明文
  2. 2 ^ $ Rounds:
  3. 哈希明文或上一轮结果。
  4. 将$ Salt附加到结果
  5. 哈希就是$ Method $ Rounds $ Result $ Salt。检查结果与数据库中记录的内容 - 如果输出匹配,则提供的明文是正确的。

答案 1 :(得分:2)

最终Security::_hash()正在内部使用,它使用伪随机盐与crypt()一起使用,这是预期的行为,没有错。

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

比较密码将正常工作,因为它将使用存储密码哈希的盐来生成匹配的哈希。

答案 2 :(得分:-1)

可能是一个可能的原因如果这将是Security.salt这应该是空的或在cakephp中使用beforeFilter。

这在你的appcontroller.php

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

现在在你的PeopleController.php

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

以及你的人物模型

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;
}