10

我的目标是为每个用户提供独特的盐,而不仅仅是Configure::read('Security.salt')为每个用户使用。

我知道 CakePHP 2.x 不再自动散列密码。这允许我对密码执行模型验证,这非常好。但是,我看不到可以覆盖 AuthComponent 的“密码”方法的方法。因此,即使我可以控制密码在保存到数据库之前的哈希方式,但我无法控制在执行实际登录时密码的哈希方式。来自食谱:

在调用 $this->Auth->login().

我该怎么做才能$this->Auth->login()使用自定义的密码散列方法?

谢谢。

更新:我最终选择了 Hannibal Lecter 博士的答案(创建自定义身份验证对象)。这是如何做到的:

旧代码:

$this->Auth->authenticate = array('Form' => array('fields' => array('username' => 'email')));

新代码(将“表单”更改为“自定义”):

$this->Auth->authenticate = array('Custom' => array('fields' => array('username' => 'email')));

创建“app/Controller/Component/Auth/CustomAuthenticate.php”并使其如下所示:

<?php
App::uses('FormAuthenticate', 'Controller/Component/Auth');

class CustomAuthenticate extends FormAuthenticate {
}

从“lib/Cake/Controller/Component/Auth/BaseAuthenticate.php”复制“_findUser”和“_password”方法并将它们粘贴到“CustomAuthenticate”类中。然后对“_findUser”方法进行如下两处修改:

  1. 从“$conditions”数组中删除这一行:$model . '.' . $fields['password'] => $this->_password($password),

  2. 更改if (empty($result) || empty($result[$model])) {if (empty($result) || empty($result[$model]) || $result[$model][$fields['password']] != $this->_password($password, $result[$model]['id'])) {

然后对“_password”方法进行如下两处修改:

  1. protected function _password($password) {通过更改为来创建“$id”参数protected function _password($password, $id) {

  2. return Security::hash($password, null, true);通过更改为来更新盐值return Security::hash($password, null, Configure::read('Security.salt') . $id);

最后,更新所有出现的AuthComponent::password以使用Security::hash与上述相同的逻辑。

4

4 回答 4

4

您可能可以创建一个自定义身份验证对象并随意散列密码。查看现有的 auth 对象以大致了解它们的工作原理。

于 2012-07-16T20:38:48.280 回答
1

您是否考虑过不使用 Auth->login() 调用,而是使用模型中当前实现的代码?(http://api20.cakephp.org/view_source/auth-component#line-506) 你可以重写它以满足你的需要。

于 2012-07-16T18:28:14.837 回答
1

对于任何想了解为什么对每个密码加盐是散列密码的正确方法的更多信息(带有代码示例),请访问:http: //crackstation.net/hashing-security.htm

也许对这里发布的代码的轻微改进是采纳我刚刚链接到的文章的建议,并生成一个“新的随机盐”......“每次用户创建帐户或更改他们的密码”。

此处发布的实现使用原始 Auth 的硬编码静态 salt 和用户 ID 作为 salt 的组合,这意味着每当用户更改密码时,相同的 salt 都会被重新使用。因此,如果您想遵循本散列指南的建议,您需要在用户每次创建/更改密码时生成一个新的随机盐,并且必须将该唯一盐与散列密码一起存储在用户表中。

您可以使用他们的随机盐生成器:

define("PBKDF2_SALT_BYTES", 24);
$salt = base64_encode(mcrypt_create_iv(PBKDF2_SALT_BYTES, MCRYPT_DEV_URANDOM));

按照惯例,将其存储在 users 表中名为“salt”的新字段中。由于代码已经为您提供了用户 ID,您可以随时根据需要存储/查找盐。

文章中还提到了“慢散列函数”一节,它使用了一种称为“密钥拉伸”的技术,以及如何使用 PBKDF2 或 bcrypt 等标准算法来实现。提供了 PHP 代码示例,可以将其复制并粘贴到您的自定义 Auth 实现中以增加安全性。

CakePHP 开发人员 Mark Story 发表了一篇关于如何 在 CakePHP 的 Auth 中实现 bcrypt的博客文章

在评论部分,Mark Story 评论说 CakePHP 2.3 将有一些新的内置特性来生成 bcrypt 哈希。

于 2012-08-14T12:50:42.037 回答
0

至少在 cake 2.3 中已经使用了一个独特的盐,即使你的配置值中的盐总是相同的。我不确定这是否适用于旧版本。

您也可以使用 Configure::write("Security.salt", $superAwesomeUserSpecificSalt); 在 User 模型中更改 beforeSave() 函数中的盐值。

于 2013-03-08T17:10:08.533 回答