4

Note: I orignally posted this over on Crypto Stack Exchange, but was pointed here instead

I'm working on a project which requires encryption of sensitive data, with communication of said data between a mobile app and a website (via an API).

I'm new to encryption and security, but my current thoughts are this:

  • Data will always be input into the app and viewed via the website, so only users of the website will need a public and private key as only they need to view the information (could use hybrid, but messages will be short)
  • Encrypt the data server-side using the public key of the correct user authorised to view the information
  • The encrypted data will be stored in the database
  • Keys will be stored on the server (not sure how this works in terms of access controls)

It is important that other users of the website are only able to see the data they are authorised to view, hence the public and private key cryptography. Obviously, querying the database here could prove difficult, but I think the use of IDs and other non-identifiable information would make it easier.

Is this a realistic idea or completely wrong in terms of how encryption works? I'm a complete beginner here, so don't know much about key management etc.

  • Welcome to Security Stack Exchange! – Bryan Field Nov 4 '16 at 18:50
  • 1
    Just to clarify, where did you envision the Private Key being stored? – Bryan Field Nov 4 '16 at 18:53
3

You're talking about generating a public/private key for each user. That's overkill. Instead, make sure you're using a signed SSL certificate with TLS 1.2 (or later) for communication between the app and your server. To understand the process better, read How does SSL/TLS work?

To keep data separate, that's where something like a session comes into play (most major web programming languages support some type of session management). Sessions store data on the server end, and then gives the user a random hash of some sort. While there's always the chance of session poisoning (where I get someone else's hash), the odds are generally low. They are no higher than trying to exchange public/private keys (which will have to be done before you send any data).

Once you have a session, you can store something like a user ID inside (the user cannot directly access this and never sees it). Then, when the user requests a record, you check to see if that user is allowed to access that record and allow/deny accordingly.

  • What about storing data in a database? Would you recommend encryption here? The data needs to be secure, imagine medical records etc. – Vanita Nov 4 '16 at 17:37
  • Done properly, you can prevent users from accessing things they should not. You don't need to encrypt the data in the DB itself. – Machavity Nov 4 '16 at 17:52
  • @Vanita it depends, you have to look at the actual requirements and risks for your data. Certain types of data mandate 'encryption at rest' i.e. any storage of these data must be encrypted and there shouldn't ever exist even a single instance of that unencrypted data written in a durable medium. It is a requirement for cardholder data under PCI DSS; for medical records (as far as I know) this is not an absolute requirement under HIPAA, but it is a very strong recommendation where you'd need to prove secure measures otherwise. Many types of data don't mandate anything, it's your choice. – Peteris Nov 4 '16 at 22:12
  • @Vanita in any case "imagine medical records etc." is a wrong approach. Medical records have one set of very specific requirements under very specific regulation. Card data have a different set of quite different very specific requirements. Nothing is "similar to medical records" or "similar to card data" - if it's not medical records, then these particular requirements don't apply, you might look at them for ideas on what's considered good practice, but it's an entirely different situation than being required to follow them to the letter. – Peteris Nov 4 '16 at 22:15
2

As mentioned in @machavity 's answer, using public private key for each user over here is not a good solution.

  • Data will always be input into the app and viewed via the website, so only users of the website will need a public and private key as only they need to view the information (could use hybrid, but messages will be short)
  • Encrypt the data server-side using the public key of the correct user authorised to view the information

What if users want to share data with each other?

  • The encrypted data will be stored in the database

While you can run queries for users individually, what if you want to run some queries on multiple users' data? Say trying to find patterns or stuff

Here is what you should consider:

  • Have users create accounts on both the app and the website. This way, you will have a unique identity of each user
  • Use access control mechanisms to ensure that a particular identity can access only the data that they have access to
  • Considering that the data is sensitive, implement TLS communication between your app and the website.
  • Leave the data in the database as it is. With exceptions of passwords of course!
1

(I'm assuming you already encrypt the connection with HTTPS which you should do.)

It is common to leave data in the database not encrypted. This is necessary to allow for querying the database in a batch format. (i.e. I want to see everyone in a particular zip code, or see who has a particular email address, what usernames are taken, etc.) Access control is possible either way.

If querying in batch format is not required, (i.e. message contents) encryption can be a good security feature. This is usually a second line of defense in case the server is compromised.

One problem with stored encryption is how to store the encryption key. If the client application is not smart/reliable enough to manage the key file then it must be stored on the server. But if you store the key on the server and encrypted data, then a hacker could theoretically get to both of them.

(Your user login Passwords should be hashed of course, not encrypted.)

Even with these issues, you should encrypt any specially sensitive information, such as Passwords to other services, SSN, super-secret documents, etc. in case your server is compromised due to some other flaw.

(Credit Card Numbers would be encrypted also, but to avoid PCI DSS issues you would outsource that to the processing gateway.)

One option is to have a single master encryption key, and just store it outside of the database. That way if a hacker uses SQLi to get to encrypted data in the database, he still will not have access to the key because it is outside the database. However for other breaches besides SQLi he would probably be able to find your key file quite readily.

If you are feeling ambitious, you can derive keys from the user's passwords like this. This would likely not be compatible with automated Password Reset feature though.

But like I said it's more common to leave data not encrypted. Particularly if the data is not overly sensitive or if you will need to use a database batch query to access all of it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.