I'm working on a small paramedical app (mainly calendar and information about the patients) that will be web hosted. The app will allow multiple accounts (1 for each practitioner) that won't share data. I want to protect the personal data as much as possible, especially to avoid 2 possible problems :
1/ a programming bug that may lead one practitioner to access data from someone else 2/ if the complete database is stolen, I want the personal information to be safe
I know that the firsts things are to avoid every sql or parameter injection but I want to take an extra steps because I'm human and I know that just one error could lead to a real mess if the data leaks... and I really want to avoid that.
- The app is based on PHP and Mysql
- the app HAS TO have a way to decrypt the personal data by it's own, because for example it sends in background emails and SMS to the patients to remind them their appointments.
- a practitioner often has a secretary that must be able to access the app with it's own login/password and see the practitioner's data (but not all of them, only the ones related to the contact information, appointment date/time...)
- of course the practitioner or secretary should be able to make a search in the database to find for example a patient by it's name, phone number... even if it's encrypted in the database.
So... I'm trying to figure out the best way to store, encrypt, decrypt the data. I'm also a little bit scared of performance, for example a search engine on encrypted data...
For now here is the simplest idea I have : 1/ when a new practitioner creates an account I generate a unique key, related to the account, that will never change, and store it in the database... it will be a kind of "salt" 2/ for every personal data, I encrypt it (for example : a patient's name, phone number) with a key composed of two parts : one which is the same for the whole application (stored in a php config file for example) + the "salt" taken from the practitioner account.
This is practical because there is no link between the practitioner's password and the app, so for example no problem for the practitioner's secretary to access the data, my email/SMS tasks to decrypt the data and if the practitioner looses his password (which is more likely to happen than the steal of the database). I first imagined to encrypt the encryption key with the (clear) password of the practitioner but then it's impossible to access the data with the secretary account or the schedule task. If I encrypt the encryption key with the hash of the practitioner's password (which is stored in the database) it's a lot more complicated and in fact adds zero security benefit.
Questions :
A/ do you think it's strong enough or am I missing something ? I know that if the complete server is compromised, the data are potentially not safe (if the hacker is smart enough to locate the key, write a code to decrypt all the data)... but that's not exactly what I fear. And I can't find any better solution which keeps the schedule task able to decrypt the data. Do you have better suggestions ?
B/ how would you encrypt/decrypt the text data ? (algorithm, key, database...) I'm really new to this in PHP and I fear making mistakes. I read the documentation but it lacks complete real life example (from key generation to text encryption/decryption). I fear utf8 problems, problems with key lengths (what are the good practices for creating a compound key from a fixed part (php config file) and a variable part stored in the database ?)...
C/ for the search engine, how would you do ? for example I want to find a person having the name starting by "ABCD" do I have a better way to do it than retrieving the whole list of encrypted names, decrypt (php) every name, put them in a list, and then (still php) make a search function inside that list ? Do you think I should encrypt/decrypt the whole data using the MySQL's AES_ENCRYPT/AES_DECRYPT functions instead ?
Thanks in advance