I have a task for my new PHP job, but I don't understand if it is possible to solve. Task:
You need to create PHP web page that implements functional on picture below. Data must be stored in SQL. Hacker can not see user phone numbers and emails even if he got access to database or files. The solutions must contain standart PHP libs.
PHP provides built-in solutions for encrypting and decrypting data. Use e.g. MCrypt, supports a good buffet of common algorithms. What exact cipher you choose is up to you, depending on the level of security required. Read up at Wikipedia on block ciphers for the general picture.
If the phone numbers must be inaccessible even if a hacker gains complete access to your system, then the decrypt key must obviously be off-server, ie. you can't store it in DB or the filesystem.
In the spec you have, this key would then be the e-mail address that's matched with the phone number. Then, at input time you'd one-way hash the e-mail, and use the unhashed e-mail as a key for encrypting the phone number. At request time, you'd find the matching phone number by using the e-mail hash, and decrypt it using the unhashed email as the key. Should get you sorted.
Update: When fetching a record that matches the phone/email pair in the database, if you've used
password_hash() (which generates a new salt and a unique string each time), then your only option is to fetch all records and iterate them through
password_verify(). That's not particularly scalable.
Unless this is an exercise in security, I'm not sure I'd bother with more than a simple
sha1() hash for the e-mails. Or use
crypt($email, '$2y$08$Some22CharsOfFixedSalt$'); -- see crypt() -- and generate e.g. a blowfish-based hash that uses a fixed salt string, resulting in an invariant hash. I'd also truncate the leading salt-part of the resulting string from the database entry.
If you're feeling crafty, why not cook up an algorithm that derives a unique string from each email, and then use that for salt in your hashing function, instead of using the same salt for hashing all e-mails.
You could also delegate the e-mail hashing for the database and use MySQL's encryption functions. Then you'd use e.g.
SHA2('email', 256) in your
SELECT queries, like so:
INSERT INTO records values (SHA2('email@what', 256)); and
SELECT * FROM records WHERE email = SHA2('email@what', 256);. Plenty of ways to accomplish this.