【问题标题】:How to use sql method “AES_DECRYPT” in afterFind in YII2如何在YII2的afterFind中使用sql方法“AES_DECRYPT”
【发布时间】:2018-04-08 04:29:00
【问题描述】:

我需要使用 AES_DECRYPT 的 sql 方法,但字符串没有解密。

它在 sql 中有效,但在 yii2 afterfind 方法中无效

它返回如下图所示的响应。

这是数据库表图像下方。

 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;

        }

【问题讨论】:

  • AES_DECRYPT 不能在afterFind() 中工作,因为它必须由 MySql 处理(您可以使用 PHP,但您很可能还想加密它在 PHP 中)。在通过修改select 查询或类似查询来获取数据时,是否可以使用AES_DECRYPT 表达式?
  • 不,先生,这对我没有帮助。
  • 确切的错误是什么?形成了什么确切的查询?看看执行的查询。您可以在调试工具栏中找到执行的查询。
  • @R13e 请查看数据库表截图。我将需要在 db 表 scrrenshot 中进行精确查询。我如何将 AES_DECRYPT 放入 afterfind 方法中。

标签: php sql yii2


【解决方案1】:

afterFind()在SQL查询完成后被调用,来不及修改查询和使用SQL表达式。您应该在调用one()all() 之前修改select 文件。

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 Server 将使攻击者能够访问加密数据,因为您在 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访问未加密的数据。

【讨论】:

  • 谢谢您,先生您的回答也对,但其他人已经回答了我。
【解决方案2】:

我希望这对你有用:

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

【讨论】:

  • 感谢先生的大力帮助。
  • 这将为每个模型创建额外的查询(在一页上显示 50 个模型将为您提供 50 个额外的查询)。看看my answer,它应该在一个查询中完成所有的魔法。
  • 另外你应该打电话给parent::afterFind()而不是return true
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-14
相关资源
最近更新 更多