4

After researching some hours about the topic of securing stored data I am a little bit confused of what is the best way to go now.

I have a databank for my (SSL) website where I am the only one that has access to it (hackers not counted). The login data is stored in a configuration file outside of the document root. In the database I have stuff like names and adresses from my clients and I am now worried that I need to implement all the security measures put forward by cryptography experts like in this answer (How do you Encrypt and Decrypt a PHP String?) or as asked here (Storing sensitive data securely in a database).

Since neither in my PDO/SQL and PHP seminars nor in regular posts here on stackoverflow I see these encryption and authentication methods being used or more specifically e.g. the keys when explaining PDO and PHP commands like INSERT INTO ... etc. I am unsure if it is now necessary to deploy encryption and authentication measures on every entry in my databank (is it even possible to do this afterwards?). The safety measures I have been informed about in the tutorials and articles are to use PDO's prepared statements.

If encryption and authentication is what I have to do, which is probably the case: Would it not be the most convenient and fastest way to simply use password_verify() and password_hash() for every sensitive data entry like it is done for passwords?

EDIT password_verify() and password_hash() are hashing (not encryption) methods, meaning that the data is irretrievably mangled and can only be confirmed but not read.

Franky2207
  • 163
  • 2
  • 19
  • Why would you *have* to implement encryption of the data you're saving? if you encrypt it, you can't use your database any more to perform searching based on that data. `password_verify` and `password_hash` are dealing with a one-way process (hashing) while encryption is a two-way process (you can get the plaintext value, whereas you can't do the same from a hash). – Mjh Jul 11 '17 at 08:10

2 Answers2

4

There are different types of database encryption, and depending on what data you want to protect, and why, you will do different things.

1) Database level encryption / Transparent data encryption

This is where your RDBMS encrypts everything for you at a file level. This means if anyone has access to the hard drive, or back-up media, they should not be able to access the data. See here for how to do it with MySQL: https://dev.mysql.com/doc/refman/5.7/en/innodb-tablespace-encryption.html (note this is not a PCI compiant solution, you'll need MySQL Enterprise Edition or another Enterprise database, or further security measures for that).

Note this does not protect your data if your application is compromised.

2) Field level encryption

You can encrypt data to be stored in any field you like. Here's a good answer that deals with that: https://stackoverflow.com/a/10945097/

The drawback of field level encryption is that you can't then query across the data. In each case you'll need to pull the data into your application, and then decrypt it one field at a time.

Note this does not protect your data if your application is compromised.

Note also the difference between 'encryption' and 'hashing' (password_verify and password_hash are about hashing)...encryption lets you secure data, store it and retrieve it. Hashing by definition does not let you retrieve the data.

In all cases the most important thing is to secure your application. Encryption of the underlying data is very much a secondary concern.

DanSingerman
  • 36,066
  • 13
  • 81
  • 92
3
  • Since your web server (presumably) will have to have access to the data, it's somewhat useless to encrypt it at rest when the web server can (will have to be able to) decrypt it. Why? Because the web server is often the weak link. If an attacker can get access to it, they can do anything it can do, including decrypting the data.

  • Encrypting data at rest is only useful to prevent backchannel leaks, like improperly handled backups (which you're doing, right, right?) which dump the data in plaintext to a file which then inadvertently gets lost somewhere. To prevent that you should use whatever at-rest encryption your database offers transparent to the client; i.e. it's not something you should burden the application logic with if it's not integral to your application, it's something the database should worry about.

  • password_hash is a hash, it doesn't encrypt data, it irretrievably mangles it so it's impossible to get the original back from it. It's great for storing credentials which you need to confirm but not read; it's useless for anything else.

  • The main security points are to isolate your database server "physically", i.e. to not grant any access to it from anything but the web server; be very restrictive and specific about that. That then means the weak spots are at those ingress points like your web server. Ensure your web server is locked down as much as possible, exposes as little attack surface as possible (no unnecessary open ports or running services) and that your application code running on it doesn't allow any exploits (yes, that's the hard part that takes knowledge and discipline).

  • You can further tighten it down by segregating access to the database with different accounts which have different permission levels; i.e. some accounts only have read access to certain tables while others have read/write access to other tables. If you can split up your web server(s) into separate roles which all only need specific limited access, this further enhances security by avoiding vulnerabilities in one part enabling exploits in another.

deceze
  • 510,633
  • 85
  • 743
  • 889
  • Let me check if I understood you right: There is no use to encrypt the data, because my web server will have access to the data. However I should use encryption methods for my backups. I need to isolate my database server "physically". I think I do not fully understand that - I only access the database via PHP and I can login to MySQL. Btw. I am using a webhosting service of a (well-known) provider that is optimized for shared-hosting-applications. According to them, a successful attack on their servers (including stealing some data) has never occured since they exist, if this info helps. – Franky2207 Jul 11 '17 at 08:51
  • 1
    Yes, if the database server itself isn't the vulnerable part (because the only way to access its data is through the web server), then it doesn't matter much whether the data is or isn't encrypted inside the database. If an attacker can get enough leverage to dump all the data from the database through the web server (because that's supposedly their only attack vector), then it's very likely they'll also be able to find the encryption keys necessarily lying around on your web server. So there isn't much of a defence against anything there. – deceze Jul 11 '17 at 08:55
  • 2
    It would only help in a scenario where an attacker can get the database data, but not the encryption keys from your server. Which is probably unlikely; if they get one, they can probably also get the other. So it's not worth the added complexity of implementing encryption inside your app; it may only add further vulnerabilities if not implemented absolutely correctly. – deceze Jul 11 '17 at 08:57
  • Thanks a lot! (Hope this doesn't count too much as spam^^). – Franky2207 Jul 13 '17 at 12:03