如何将密码解密为真实密码以显示在更新表单Yii2(高级模板)中


How to decrypt password to real password to be shown in update form Yii2 (Advanced Template)?

我想以更新形式显示解密密码作为行

<?= $form->field($model, 'password_hash')->passwordInput() ?>

显示完整的加密密码,例如:

$2y$13$4SUKFKV03ZolfDwLIsZRBuD4i7iELPZRMEJojODgP3s5S4dER.J0m

它是123456的加密密码

正如@TomCarrick已经提到的,散列密码是一种单向算法,永远不会被逆转。验证建议密码有效性的过程是使用相同的算法对其进行哈希处理,然后检查生成的哈希是否与您已有的密码相同。这个策略在 Yii 中在 User 类中处理,该类扩展了 IdentityInterface 并在您的配置文件中定义。这是在这两种方法中完成的:

class User extends ActiveRecord implements IdentityInterface
{
    ...
    public function validatePassword($password)
    {
        return Yii::$app->security->validatePassword($password, $this->password_hash);
    }
    public function setPassword($password)
    {
        $this->password_hash = Yii::$app->security->generatePasswordHash($password);
    }

注意:不建议执行以下操作。如果是更新形式,例如用户更改密码,正如我从您的问题中理解的那样,那么我会 建议使用两个输入:old_passwordnew_password 在大多数网站中。然后与在 User 类中实现的方式相同, 您可以通过比较哈希值来检查内部密码的有效性,如果 它是有效的,然后您只需对new_password进行哈希处理并将其保存到 通过覆盖旧数据库。

如果出于某种原因,您需要知道用户的密码,那么您将需要通过实施不太安全的策略来手动更改 Yii 设置和验证这些密码的方式,这可以通过用不同的算法替换单向算法来实现,例如使用 encryptByPassword() 和 decryptByPassword() 辅助方法,这将允许您使用稍后将使用的$secretKey加密任何字符串将其解密回来。因此,您需要通过以下方式覆盖前面提到的 2 种方法:

public $secretKey = 'WHATEVER_SECRET_YOU_CHOOSE';
public function validatePassword($password)
{
    $decryptedPassword = Yii::$app->getSecurity()->decryptByPassword($this->password_hash, $this->secretKey);
    return $decryptedPassword === $password;
}
public function setPassword($password)
{
    $this->password_hash = Yii::$app->getSecurity()->encryptByPassword($password, $this->secretKey);
}

如果需要,您还可以在模型中实现 setter 和 getter 方法,例如:

public function getPassword()
{
    return Yii::$app->getSecurity()->decryptByPassword($this->password_hash, 'THE_SECRET_YOU_ALREADY_HAVE_CHOOSEN');
}
public function setPassword($password)
{
    $this->password_hash = Yii::$app->getSecurity()->encryptByPassword($password, 'THE_SECRET_YOU_ALREADY_HAVE_CHOOSEN');
}

您可以使用任何地方来检索真实密码,并至少在数据库中保留它的解密版本:

<?= $form->field($model, 'password')->passwordInput() ?>

您还可以在此处找到有关安全帮助程序方法的更多信息。

你不能。这就是散列密码的全部意义,因此它们不能反转为原始明文。