AES_ENCRYPT in model

On model level, we can always encrypt value in function beforeSave, but i don't know how to make fetch in the same way, so when i fetch data, there are automatilcy AES_DECRYPT. I want to do this without phsql.

public function beforeSave(){
    $this->name = new RawValue('AES_ENCRYPT("'.$this->name.'", "secret_pass")');
}

So when i do this, it's work properly, so name is encrypted in blob field in database

$model  = new Model();
$model->name = "abc";
$model->save();

but i don't know how to fetch unencrypted data directly from model, similar to this:

$data = Model::findFirst();

or

$data = Model::find();

afterFetch. Keep in mind events are runned only if you return full models. So if you will get only some columns they will not be runned.



2.6k

I test afterFetch , and it's not working i try this

public function afterFetch(){
    $this->patient_first_name = new RawValue('AES_DECRYPT("'.$this->patient_first_name.'", "secret_pass")');
}

and model do not decrypt this



1.6k
edited Jan '17

You don't need RawValue in afterFetch() Try ` $this->patientfirstname = AESDECRYPT($this->patientfirstname, "secretpass"); `

Why code formating is not working on mobile?

You need to use php function here. Not RawValue.



2.6k

Do you have example how to do that ?, so, what i should exacly put in function afterFetch to decrypt this value ?

Use openssl_decrypt

You should first decide where to put the encrypt/decrypt logic. You CAN have encryption on SQL and decryption on PHP side, but that requires you to share the same encryption key between the two systems (bad idea).

Phalcon has built-in security methods, you'd be better off using that (you also have more control over the key/algo/padding).

https://docs.phalconphp.com/en/3.0.0/reference/crypt.html#setting-up-an-encryption-service

$di->set(
    "crypt",
    function () {
        $crypt = new Crypt();
        // Set a global encryption key
        $crypt->setKey(
            "your secret goes here"
        );
        return $crypt;
    },
    true
);
public function beforeSave(){
    $this->name = $this->getDI()->get('crypt')->encryptBase64($this->name);
}
public function afterFetch(){
    $this->name = $this->getDI()->get('crypt')->decryptBase64($this->name);
}


28.4k

good topic !



2.6k
edited Jan '17

OK, about build in crypt function, i know about this, this was not the question about changing the way to encrypt, but question about AES_DECRYPT in model ;)

BUT ! Based on internet post, i write that part of code

private function mysql_aes_key($key)
{
        $new_key = str_repeat(chr(0), 16);
        for($i=0,$len=strlen($key);$i<$len;$i++)
        {
            $new_key[$i%16] = $new_key[$i%16] ^ $key[$i];
        }
        return $new_key;
}

private function decrypt($field)
 {
        $key = $this->mysql_aes_key("secret_pass");

        $val = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $field, MCRYPT_MODE_ECB, mcrypt_create_iv( mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB), MCRYPT_DEV_URANDOM));

        return trim($val);
}

and now in after fetch function

public function afterFetch(){
        $this->patient_idx = $this->decrypt($this->patient_idx);
}

But there are some dummy characters sometime in data, i think i be able to solve this more less in next comming days, so i post answere here ;)

You can also use just phalcon crypt service :D



2.6k
edited Jan '17

Can you put the code, how can i use crypt service to decrypt AES_ENCRYPT value in database ?

public function afterFetch()
{
    $this->patient_idx = $this->getDI()->get('crypt')->decrypt($this->patient_idx, 'secret_pass');
}

Of course decrypt service must be set with correct cipher etc.

mcrypt is now earmarked as deprecated, any decent dev would refrain from building a project which utilizes it. As we advised, the best approach for this is to drop mcrypt altogether, and use the built-in methods of Phalcon.

If you want to stick with mcrypt, it's up to you, but don't come looking for help on the dedicated channel for Phalcon ;] (no offense intended)