afterFind()
is called after SQL query was performed, it is too late to modify query and use SQL expressions. You should modify select
fileds before you call one()
or all()
.
return MyModel::find()
->addSelect(['cast(AES_DECRYPT(encrypt_name, "key test") as char) as name'])
->one();
You may override find()
method in your model to do this automatically for every query:
public static function find() {
return parent::find()
->addSelect(['cast(AES_DECRYPT(encrypt_name, "key test") as char) as name']);
}
You may reconsider not using AES_DECRYPT
at all. When it comes to encryption, for security reasons, it is better to encrypt as soon as possible and decrypt as late as possible. Moving encryption at SQL level introduces several threats:
- Your SQL query could be logged (in error or slow-query log) or displayed in exception message. This will reveal your encryption key, making whole encryption quite pointless.
- Since you're sending encryption key and unencrypted data between PHP and MySQL server, the attacker can get access to them using MITM attack.
- Compromising SQL server will give attacker acces to encrypted data, since you're sending encryption key quite often in SQL query.
You can avoid this by encrypting and decrypting data at PHP level (using Yii security component or some library). You can make this transparent by creating virtual attribute via setter and getter:
public function getName() {
return $this->decrypt($this->encrypted_name);
}
public function setName($value) {
$this->encrypted_name = $this->encrypt($value);
}
Then you can access unencrypted data by $model->name
.