简体   繁体   中英

Cross-Platform encryption for Database

Let's say I have a MySQL database into which users can enter some personal data like postal addresses via a php website. The users can NOT log into this site to later verify what they have entered. The enterprise they have entered their data for (voluntarily of course) then can use this data to maybe send the users actual mail (you know, postal services and such) or emails (of course the users agreed beforehand that they want to receive emails). The database serves merely as a store for the data and I want it to be a bit safe. If anyone breaks into the database, retrieving the email address and the actual first and last name (many email addresses contain both anyway) might not do much harm, but knowing where people live could be too much of a giveaway.

The enterprise is accessing the database via a C# front-end that targets stored procedures within the database to do stuff, including searching for users based on their email address.

From what I have gathered through searching I could think of the following procedure to handle the personal data in a more secure way (than saving them as plain text in the database)

  • before submitting the sensitive information to the stored procedures the plain text gets encrypted with a key while still in php, so all the MySQL server logs see is encrypted data
  • the front-end uses the same key to make the data humanly readable again when it is displayed to the enterprise's users (They need to access this private information and the user is comfortable with the enterprise doing so, that's the whole point of this scheme)

My line of thinking is: These are not passwords that are stored so I don't need all the password hashing trickery (As I understand it, when securely saving a password in a database, you use a one way algorithm, so you can never reverse engineer the password straight from the database but have to hash every password you want to try and test that against the desired database entry to see if you chose the right password) but can instead go for a simple encrypt/decrypt, because I don't want to brute force every address out of the database.

There are a few rough edges that raise concerns for me:

  • I need to somehow provide the key I want to encrypt by to php. Usually this is done via a library or external php document, like you provide the database connection information in a separate php file which resides in a folder on the server which is not accessible from the web (The server will say access denied if you try to access it) Is this a good practice and can I be sure that this key-file is really safe?
  • I need to provide the key to the front-end as well. This should be done separately in a (maybe encrypted?) config file for the front-end. Is it wise to have the key in two places, albeit for two different systems? The key must never change or else part of the data will be lost!
  • Somehow I have the feeling that if someone knows how to access the database he/she probably figured out where the connection data was and how that was to be accessed. Oh look, here is an encryption key, I wonder what that does. How likely is it that if the database access is breached the encryption key is in the open as well rendering all efforts to give a little extra of privacy to the users void?
  • If I wanted to add another bit of "extra security" and encrypted the email address as well I would have to encrypt every email address I want to search for from the php or the front-end, right?
  • Having searching procedures using ´RLIKE´ will break on encrypted fields, won't they? So to retain searching for parts of an email address I cannot encrypt the email entry, right?
  • I will have to change my database fields to binary to accommodate encrypted data or make them bigger and base64-encode them, won't I?
  • Is there an encryption/decryption algorithm ready to use in PHP 7.0.7 and C#? (I don't worry that much about C#) One that is reasonably secure while not bloating my tiny texts to massive chunks of binary? I don't know if that is of any consequence, but if I use for example a 256 bit key, that's 32 bytes. If the street part of the address is shorter that 32 characters, will the encryption work? Will there be cumbersome padding involved?

All in all I feel that the security gain is minute compared to the measures I have to take in my php files as well as in the code for the front-end. The perceived security gain might be bigger ("Woha! They are saving our data encrypted! They sure know what they are doing!"). Having strict and restrictive privileges for certain types of users (for example revoke ´SELECT´ commands) should in all be more helpful, shouldn't it?

Edit for @Luke Joshua Park:

Thank you for your detailed answer. I suppose by API server you mean the webserver my php's reside on? This indeed should be separate from the database server. Both servers are hosted within a university's network but can be accessed from the internet.

I can follow the authentication path to the point where every user from within the enterprise (small-ish project at said university, maybe a bad choice of wording) has a database user with sensibly set grants. But users from outside using the php only send data to be stored in the database (ideally with a common but seperate database-user with grants set accordingly), and never retreive (their own) data. Using authentication would mean they first had to create an account (which is not needed) and how do they authenticate themselves for creating the unwanted account?

It is good that you're asking these questions before implementing a solution, cryptography is difficult to get right and a sound understanding is required before you start.

I'll answer your questions quickly first, but the more important part is what follows.

  • Not really. See below.
  • Yes, in most cases, keys should be kept on the device they are created on, wherever possible.
  • Provided your API server(s) doesn't also have the database on it, relatively unlikely.
  • Yes.
  • Yes.
  • Yes. But don't base64 them. Wasted space and processing power for no benefit.
  • You're asking the wrong questions. An algorithm isn't "for" a language. You just need to pick the right algorithm/block mode/padding depending on your needs.

For the most part the questions you are asking are irrelevant. Believe it or not, your issue is more to do with authentication than it is to do with encryption.

The first thing you need to understand is that a server breach is a server breach. Bad stuff is going to happen regardless of how much cryptography you throw at it. But we can minimize damage where possible.

Your database software should be running on a separate server/instance/whatever from your API server. Encryption/decryption should only take place on your API server. This has the benefit that both your API server and database server would have to be breached in order to decrypt the data (to access the keys). How you store the keys on your API server isn't all that important provided they aren't in your webroot or something silly like that.

Everything past this is authentication. You need a strong authentication system to determine who can send you information and who can retrieve information from you. Communication to and from your API server should obviously be encrypted with TLS at all times. You might consider TLS client authentication as a way to ensure the entity requesting data from you is who they say they are. Usually client authentication can't really be used on the web, but if you're interacting with "enterprises" in a more private way, then client authentication is an excellent choice.

In summary:

  • Separate your API server from your database server. Encryption keys should only ever be on the API server. See this repository for a collection of encryption examples from PHP to just about any other language.

  • Use TLS for all ingoing and outgoing communication.

  • Focus on authentication. TLS Client authentication is a good option.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM