I wanted to share interesting approach to storing sensitive data in DB where the same has to be encrypted and decrypted gracefully. I’d like to point out that there is a difference between sensitive data that needs to be stored for usage in plain form and sensitive data that needs no lain form presentation (passwords). Common use of passwords: Passwords are never decrypted as that presents a security weakness by allowing 3rd party to intersect the plain form password and use it to take over the existing or create new “valid” session as someone else (someone with legitimate privilege to do so). To prevent this from happening passwords are kep in form of a hash value and validation is performed as comparison of repeated hash calculation of validated string against existing hash string in DB. With data set where sensitive data like API keys for different sub-services and every time API key needs to be used to establish new connections to API servers these keys refer to, we want to have a safe way of decrypting these keys - use them - close the connections. To address just one term used here: “safe way of decrypting”, whatever you do it’s only way of decrypting data - safe, unless you are transporting decrypted data or keys through unprotected channel. In a localized environment we want to grab the encryption key, decrypt data and use it. The idea behind this post is to define a new level of encrypted data store in environment where encrypted data is transferred through potentially unsafe channel and there could be justified threat of a man in the middle attack. Good approach is to have a matrix that is capable of generating pseudo random arrays subsequently and mix it with secondary source of PRNG as required per individual basis. This will be used to generate master encryption key. Eventually the data flow and encrypt - decrypt flow should be as follows:
To prevent efficient brute force attack regeneration of NEW master key was set to happen on 2 minute basis. Generating new master encryption key happens by the steps described on the scheme below:
$chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $charsLen = strlen($chars); $initial_secret = ''; for ($i = 0; $i < 22; $i++) { $initial_secret .= $characters[rand(0, $charsLen - 1)]; }
I’ve chosen to go with RIJNDAEL-256 and following implementation described on scheme below.
This is the process I’ve cron’ed to 2-minute cycles. These were my two cents on having fun with encryption and inventing new ways to complicate things :)
Fill out the enquiry form and we'll get back to you as soon as possible.
Fill out the enquiry form and we'll get back to you as soon as possible.