Using Csecuritymanager To Encrypt/decrypt Data

I’m working on a project where I need to store some private sensitive information. I wanted to use CSecurityManager to encrypt/decrypt the data in the database. I had a lot of problems getting it work, and couldn’t find much information, so I thought I’d post what I did. Here are the results.

I’ve set up a simple table to work with.




CREATE TABLE `information` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `record_name` varchar(45) NOT NULL,

  `private_info` varchar(255) NOT NULL,

  `sensitive_data` varchar(255) NOT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB CHARSET=utf8;



Note the charset, this is important later on.

I’ve used gii to create my models and crud, everything stock but I’ve put the following in my model.




    public function beforeSave() {


        $this->private_info = Yii::app()->getSecurityManager()->encrypt($this->private_info);

        $this->sensitive_data = Yii::app()->getSecurityManager()->encrypt($this->sensitive_data);


        return parent::beforeSave();

    }


    protected function afterFind() {


        $this->private_info = Yii::app()->getSecurityManager()->decrypt($this->private_info);

        $this->sensitive_data = Yii::app()->getSecurityManager()->decrypt($this->sensitive_data);


        parent::afterFind();

    }



This saves empty values to the db, so I added the following to my config/main.php under components.




    'components' => array(


        'securityManager'=>array(

            'cryptAlgorithm' => 'rijndael-256',

            'encryptionKey' => 'ThisIsMySecretKey',

        ),



To find a list of valid values for cryptAlgorithm use:


print_r(mcrypt_list_algorithms());

My result was:




Array

(

    [0] => cast-128

    [1] => gost

    [2] => rijndael-128

    [3] => twofish

    [4] => arcfour

    [5] => cast-256

    [6] => loki97

    [7] => rijndael-192

    [8] => saferplus

    [9] => wake

    [10] => blowfish-compat

    [11] => des

    [12] => rijndael-256

    [13] => serpent

    [14] => xtea

    [15] => blowfish

    [16] => enigma

    [17] => rc2

    [18] => tripledes

)



Still getting an error however. The problem is the UTF-8 encoding. I tried my db default encodings, and they weren’t working, so UTF-8 and encode/decode seemed to do the trick. So my model now looks like this:




    public function beforeSave() {


        $this->private_info = utf8_encode(Yii::app()->getSecurityManager()->encrypt($this->private_info));

        $this->sensitive_data = utf8_encode(Yii::app()->getSecurityManager()->encrypt($this->sensitive_data));


        return parent::beforeSave();

    }


    protected function afterFind() {


        $this->private_info = Yii::app()->getSecurityManager()->decrypt(utf8_decode($this->private_info));

        $this->sensitive_data = Yii::app()->getSecurityManager()->decrypt(utf8_decode($this->sensitive_data));


        parent::afterFind();

    }



Ok, so everything works now. There is one more change I wanted to make, and that was to encrypt each field with a different key. Logic tells me that if the data is compromised and the key for one field is cracked, the other fields will need to be cracked individually, making it harder to get at. Maybe I’m out to lunch. IDK.

So this is what my model looks like now.




    public function beforeSave() {


        Yii::app()->getSecurityManager()->setEncryptionKey('PrivateInfoEncryptionKey');

        $this->private_info = utf8_encode(Yii::app()->getSecurityManager()->encrypt($this->private_info));

        

        Yii::app()->getSecurityManager()->setEncryptionKey('SensitiveDataEncryptionKey');

        $this->sensitive_data = utf8_encode(Yii::app()->getSecurityManager()->encrypt($this->sensitive_data));


        return parent::beforeSave();

    }


    protected function afterFind() {


        Yii::app()->getSecurityManager()->setEncryptionKey('PrivateInfoEncryptionKey');

        $this->private_info = Yii::app()->getSecurityManager()->decrypt(utf8_decode($this->private_info));

        

        Yii::app()->getSecurityManager()->setEncryptionKey('SensitiveDataEncryptionKey');

        $this->sensitive_data = Yii::app()->getSecurityManager()->decrypt(utf8_decode($this->sensitive_data));


        parent::afterFind();

    }



I hope this helps someone. And please if you have any suggestions let me know, I could use them.

One more thing I forgot. Remove encrypted fields from searches, they will not be searchable of course.

hey,

First of all i want to thank you for your great explanation!

I followed your steps and also wanted to use rijndael-256.




'securityManager'=>array(

    'cryptAlgorithm' => 'rijndael-256',

    'encryptionKey' => 'ThisIsMySecretKey',

),



I checked my databases and my tables for correct encoding:




CREATE TABLE IF NOT EXISTS `test` (

  `Id` int(11) NOT NULL AUTO_INCREMENT,

  `User_Id_From` int(11) NOT NULL,

  `Text` text NOT NULL,

  `Room` varchar(200) NOT NULL,

  `Date` datetime NOT NULL,

  PRIMARY KEY (`Id`)

) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;



I also checked the default charset of the CApplication.

So everything looks fine. But when i test it, it seems to be a bit random.

Most of the time it works well but sometimes it just display some random chars.

For example if i insert in my test table a string "Hello world!" a few times, the encoded strings looks fine in the table. But the decoded strings are not decoded correctly everytime.

1.) Òã´D\‹Ëc+ŇçÅB)(IÕÃ(žùšý4ÖéÇ[ïÖǯãbÝõ>–A”=ð

Ï4›Þ^MP;

2.) ñð)aÀ0"ÜC½†ß0
`ŠO­Íes™[o¼×y´“Í겉€ûç+² ;Š

Ž3±[á«_â†eБ,’l½\

3.) Æv£§Û?é³;ue|OÌ¯ß a¶ÃOÚ]MËãh-5ÀƒU›ÍìâW£S>ÚY4ëFә˜]ۙZ¯@Q

4.) íJ؂p(èO³î„"®Õg

ÍԌNš:y—ýÔ
Fà8®ªhŸ‰ogŽÛS\9(£¼“¨ô)äÎ

5.) “UÖGشЉïj>ÜÊòÌ5¶±2Ùú“’£/®48o›fièGÒ¹»Ž’M?‡Ð‡õžÉö$×Ñ#


  1. decodes correctly

  2. decodes correctly

  3. wrong decoding

  4. decodes correctly

  5. wrong decoding

I dont understand what my problem is. Can anyone please help me out here!

Thank you!

I found the solution by myself.

The problem was the method of the php decode and encode…

Use instead of utf8_encode/decode -> base64_encode /decode

cheers

It might seem like an outdated post but I am currently trying to get the encryption working.

I have checked that Mcrypt extension is installed in my localhost. I have setup the as per advised above but unfortunately, I am unable to get it to work. It is still saving raw in database.

Saving works fine in database. Am I missing a step or have used component wrongly?

Main.php




	// application components

	'components'=>array(


		'user'=>array(

			// enable cookie-based authentication

			'allowAutoLogin'=>true,

			'class'=>'RWebUser',

                // enable cookie-based authentication

                'allowAutoLogin'=>true,

                'loginUrl'=>array('/user/login'),

		),

		

		'securityManager'=>array(

            'cryptAlgorithm' => 'rijndael-256',

            'encryptionKey' => '9519FAB0C0CE28A2',

        ),



Model




	public function beforeSave() {

        if(parent::beforeSave()){

            if ($this->isNewRecord) {

				$this->updated_on = date("Y-m-d H:i:s");

				$this->updated_on = $this->updated_on;

				$request = Yii::app()->request;

				$form = $request->getPost('Salary');

				$sum = $form['salary_other_entities']+$form['handphone_allowance']+$form['transport_allowance']+$form['transport_others_allowance']+$form['acting_allowance']+$form['acting_re']+$form['acting_rto']+$form['lew_allowance'];

                $this->salary = $sum;

                $this->salary = $this->salary;

				$sum = Yii::app()->getSecurityManager()->encrypt($sum);

            } else {

				$request1 = Yii::app()->request;

				$form1 = $request1->getPost('Salary');

				$sum1 = $form1['salary_other_entities']+$form1['handphone_allowance']+$form1['transport_allowance']+$form1['transport_others_allowance']+$form1['acting_allowance']+$form1['acting_re']+$form1['acting_rto']+$form1['lew_allowance'];

                $this->salary = $sum1;

				$this->updated_on = date("Y-m-d H:i:s");

				$sum1 = Yii::app()->getSecurityManager()->encrypt($sum1);

            }

            return true;

        } else  {

            return false;

        }

 



Any help is greatly appreciated.

Managed to get it working. Was unable to use a variable declared thus I just used $this->salary.

Thank you.

On executing this i received an error like this Access level to app\models\Information::afterFind() must be public (as in class yii\db\BaseActiveRecord).

Can you please explain this topics in detailed with the proper code.

this not working
Call to undefined function mcrypt_module_get_supported_key_sizes()
it will give me error
can enyone help me in encrytption and decryption