如何在YII2中的afterFind中使用sql方法“AES_DECRYPT”

时间:2018-04-04 10:41:07

标签: php sql yii2

我需要使用AES_DECRYPT的sql方法,但字符串不会被解密。

它在sql中工作但不在yii2后找到方法

它返回如下图所示的响应。 enter image description here

这是在db表映像下面。 enter image description here

 public function afterFind() {
            parent::afterFind();

            //$this->name = new Expression('AES_DECRYPT("'.$this->name.'", "key test")  as name ');
            $this->name = new Expression('cast(AES_DECRYPT("'.$this->encrypt_name.'", "key test") as char) as name');

            //return true;

        }

2 个答案:

答案 0 :(得分:2)

执行SQL查询后调用

afterFind(),修改查询并使用SQL表达式为时已晚。在致电selectone()之前,您应修改all()个文件。

return MyModel::find()
    ->addSelect(['cast(AES_DECRYPT(encrypt_name, "key test") as char) as name'])
    ->one();

您可以在模型中覆盖find()方法,以便为每个查询自动执行此操作:

public static function find() {
    return parent::find()
        ->addSelect(['cast(AES_DECRYPT(encrypt_name, "key test") as char) as name']);
}

您可能会重新考虑不使用AES_DECRYPT。在加密方面,出于安全考虑,最好尽快加密并尽可能晚地解密。在SQL级别移动加密会带来一些威胁:

  • 您的SQL查询可能会被记录(在错误或慢查询日志中)或在异常消息中显示。这将揭示您的加密密钥,使整个加密毫无意义。
  • 由于您在PHP和MySQL服务器之间发送加密密钥和未加密数据,因此攻击者可以使用MITM attack访问它们。
  • 由于您在SQL查询中经常发送加密密钥,因此妥协SQL服务器会使攻击者访问加密数据。

您可以通过在PHP级别加密和解密数据来避免这种情况(使用Yii security componentsome library)。您可以通过setter和getter创建虚拟属性来使其透明:

public function getName() {
    return $this->decrypt($this->encrypted_name);
}

public function setName($value) {
    $this->encrypted_name = $this->encrypt($value);
}

然后,您可以$model->name访问未加密的数据。

答案 1 :(得分:1)

我希望这对你有用:

    public function afterFind() {
        $this->name = (new Query)->select(['AES_DECRYPT("'.$this->encrypt_name.'", "key test") as name'])->scalar();
        return true;
    }