AES Encryption

Thank you Paystey … That is what I was doing … but I’m not sure of the syntax for that. I tried a few different ways but nothing seemed to work for me …

Just use standard array syntax, it’s just an array of attribute (column) names, so clientSocialSecurity, I’m guessing, is the field you’re currently encrypting/decrypting in the database. So replace the ‘Some’ and ‘More’ etc. parts of this line with those attribute (column) names:

array(‘clientSocialSecurity’, ‘Some’, ‘More’, ‘Attribute’, ‘Names’),

This breaks, but I’m sure I’m not doing something right:




'attributes'=>array('clientSocialSecurity','insurancePolicyNumber','insuranceSubscriberDOB','insuranceSubscriberSSN'),



The behavior is parsing a key and a value so I think I need to pass things differently:




   foreach ($this->getOwner()->getAttributes() as $key => $value)




Ah yes, that’s exactly the syntax I meant. So no I have no idea, and am far too tired to walk through it closely enough :)

I’ll give it read tomorrow morning if antonio hasn’t already answered. I’ve got a bit of a vested interest in this as I’m looking at something similar in the future :P

Ok I’ve given it a read through and came to the same conclusion I did last night. Adding to the attributes parameter of the behaviour should then also affect those parameters when they are saved and loaded.

Is the field in the database already encrypted or in plain text? A plain text in the DB will be decrypted to gobbledegook on the way out and then encrypted back to “plain text” on the way in, therefore you won’t notice a difference. Make sure it’s the encrypted value that’s in the database when you begin.

Other than this, sorry, I’ve no idea that seems like exactly how it should work. You could try posting your whole model class as you have it here and I’ll take a look over it make sure theres nothing that should stop you?

Hi Paystey,

Thanks again for looking at this with me.

Yes, the values in the database already are encrypted. I can run a query directly against the database and see that they can be decrypted properly using a simple AES_DECRYPT in MySQL.

In the behavior function call, I can call the clientSocialSecurity and it displays properly decrypted in the view page. But if I add another field (insurancePolicyNumber, for example), the clientSocialSecurity appears fine, but the insurancePolicyNumber is empty. The same is true if I add multiple fields (which I eventually need to do).

If I print the key and value from within the CryptBehavior class, I see that it is indeed getting the right fields and encrypted values:

clientSocialSecurity | C� ��zH{��\-$m�

insurancePolicyNumber | :7³”»ÆºcÕÅáN½óÔ

So, it appears something is happening perhaps with how it is returned?

Here is how the afterFind works:




 public function afterFind($event)

        {

        foreach ($this->getOwner()->getAttributes() as $key => $value)

          {

          if (in_array($key, $this->attributes) && !empty($value))

           {

            echo "$key | $value<br />"; 


            if ($this->useAESMySql)

            $this->getOwner()->{$key} = $this->mysqlAESDecrypt($value, Yii::app()->securityManager->getEncryptionKey());

            else

            $this->getOwner()->{$key} = Yii::app()->securityManager->decrypt(utf8_decode($value));

            }

          }

        return parent::afterFind($event);

        }




Thanks for your time.

Christopher

Uhm, I probably should have mentioned this earlier, but: If decryption fails, NULL is being returned. Could explain the "empty" fields.

That is exactly what is happening… if empty/failed… then NULL/FALSE/GIBERISH data is returned…

Very happy you got decryption working :)

Cheers

I’m not sure this is the answer but could it be the rules defined in the model? If the ‘[color=#1C2837][size=2]insurancePolicyNumber’ is not defined as safe I’m not sure whether it will be allowed to be set. I have a feeling this is only checked on save() though and you shouldn’t have a prblem just putting it in the attributes array. Could you post your rules() function from the model class? [/size][/color]

[color=#1C2837][size=2]

[/size][/color]

[color=#1C2837][size=2]Or if you know how, just add the [/size][/color][color=#1C2837][size=2]insurancePolicyNumber to the safe rules.[/size][/color]

[color=#1C2837][size=2]

[/size][/color]

[color=#1C2837][size=2]If not then like Da:Sourcerer says it could just be failing the decryption somehow? No idea how though as it’s using the same mechanism to decrypt both and the same mysql method works to decrypt both I guess?[/size][/color]

Isn’t this a gross missunderstanding? From what I know, the safe validator will allow attributes to be massively assigned. This won’t affect them when being loaded from the DB but rather has a major role when a models attributes are being filled from e.g. a form.

I wasn’t sure, I know on saving it does the validation check, but wasn’t sure if it could be stopping the $this->getOwner()->{key} = from setting it too. Slim chance I know but I had no time to look it up. But as I say, probably not.

Nope, this single assignments are okay for “unsafe” attributes. But they won’t be filled by something like $model->attributes=$_POST[‘Model’]

Then it is my fault for not including what you just said… but if he tries to make a model out of a Form and setting its attributes, the ecryption will fail on save.

Christopher, can you perhaps paste the full code of your model? I think any further advice will otherwise just be an uneducated guess.

I was glad to find this example when I kept getting errors trying to use CSecurityManager. Thanks!

But I’d like to point out a potential flaw with these particular routines. The code works for two-way encryption-decryption – but only because ECB mode ignores the initial vector (iv) parameter. A random iv (as coded) just isn’t going to work if you use a mode, such as CBC, that actually uses the iv parameter. In that case you either have to always use the same iv for encryption and decryption, or you have to store the generated iv along with the encrypted data so you can use the same iv to decrypt.

ETA: I’ve beem examining the code in CSecurityManager. If you look at the encrypt and decrypt methods you see that the encrypt method generates a random iv when encrypting and prepends it to the encrypted value. The decrypt method then slices the string, using the first part as the iv and the second as the value. That’s a behind-the-scenes implementation of the second option I mentioned in the previous paragraph.

Would like to breath some life back into this thread.

I have implemeneted a model for USER that I would like to use on login but it seems to be doing some strange things.

I set password to the AES Encrypted string…maybe that is my problem user_password in the table is VARCHAR(50)

Is that a problem?

I think I am pretty close based on my debugging the first attempt. I followed Mr Ramirez’s directions and updated the value in the table so that it was encrypted. I put a couple debug lines on the login form but the password decrypted did not

work the same…that might be due to the internal function mysqlAESDecrypt($val, $ky) being invoked. I could not call it from my simple test in the login.php file.

Do I need to use VARBINARY ?

Well, encrypting user passwords isn’t a very good idea. Instead, you should consider hashing them via bcrypt or similar.

As far as your question goes: Yes, you would need a VARBINARY field.

And ragarding the problems a few pages earlier: It seems CSecurityManager is actually using the MD5 sum of the supplied key for en- and decryption.

Thank you Da:Sourcerer ! Both for the advice and the clarification .

I will look into bcrypt and other options.

Da:Sourcerer,

One additional question. If I use the phpass example you posted, (which seems to work if I set my password hashed in the db)

what kinds of modifications to the User model do I need to make for maintaining the user record. Is it as simple

as adding Password1 and Password2 fields to the _form and removing the password field?

Thanks !

Well, yes :)