我想在symfony2中创建一个使用用户数据库表的登录。登录使用编码器“plaintext”,“sha1”(1次迭代,encode_as_base64:false),“sha512”(1次迭代,encode_as_base64:false)运行。
令人惊讶的是,它没有运行多次迭代。
我的“security.yml”中有一个“chain_providers”语句,其中包含两个提供程序“in_memory”和“user_db”(=使用用户数据库登录)。第一个没有问题。
让我们使用两个迭代例如:
“security.yml”:
security:
encoders:
Customer\MyBundle\Entity\User:
algorithm: sha512
iterations: 2
encode_as_base64: false
...
user_db:
entity:
class: Customer\MyBundle\Entity\User
property: login
现在我计算一个新密码哈希:
php -r '$pw = "new2"; $iter = 2; for ($i = 1; $i<= $iter; $i++) $pw = hash("sha512", $pw); print "pw ($iter): $pw\n";'
我将其写入用户实体(MySQL表)的“密码”列:
update User set password = "239055fb839647cfd3d58d542db192aae36f108ebbe1a16e71d25178bc455b6a94e81e34fd96f8953663d9a3206ad23512d4b79ea78cc1f0bdbcc08275c732b6" where login="test";
我应该能够立即登录,但我得到的只是“凭据不好”。
我的用户实体实现了“UserInterface”接口。我的getSalt()方法返回一个空字符串或null(都经过测试)。 getUsername()或getRoles()没有什么特别的。
迭代有什么问题? 为什么它只运行“iterations:1”/“$ iter = 1”?
答案 0 :(得分:1)
多次散列密码的创建方式与预期不同。
MessageDigestPasswordEncoder :: encodePassword($ raw,$ salt)中的代码是:
...
$salted = $this->mergePasswordAndSalt($raw, $salt);
$digest = hash($this->algorithm, $salted, true);
// "stretch" hash
for ($i = 1; $i < $this->iterations; $i++) {
$digest = hash($this->algorithm, $digest.$salted, true);
}
return $this->encodeHashAsBase64 ? base64_encode($digest) : bin2hex($digest);
..使用“mergePasswordAndSalt()”返回空$ salt的$ raw密码。
换句话说:对于空$ salt,它会在每次迭代中将原始密码附加到散列密码。
要离线生成新密码,我们需要更改此代码:
$pw = "neu";
$digest = "";
$salted = $pw; // for emtpy salt
for ($i = 1; $i<= 4398; $i++)
{
$digest = hash("sha512", $digest . $salted, true);
}
print base64_encode($digest) . "\n";
// now write the generated code into the password in the database table
并在security.yml中设置:
security:
encoders:
Customer\MyBundle\Entity\User:
algorithm: sha512
iterations: 4398
encode_as_base64: true