0

I'll save you the detail of the issues, but do let me know if you need any additional info that I'm not mentioning here.

The basic set up is that I have a web application, and on the browser the user will enter some relatively sensitive information that will be transmitted to the server through https. Unlike passwords for logins, these information submitted by the users will need to be available/readable to the users in the future, and hence reversibly encrypted.

I have found a few relevant posts, but I am not sure if I completely understand them. My initial thought was as follows:

  1. Ask the user to submit a passcode along with their sensitive info.
  2. On the server side, I encrypt the sensitive info using their passcode through AES etc.
  3. I store the encrypted info in my database, and discard the passcode.
  4. When the user needs to see the sensitive info, I ask them to type in the passcode again, which is then sent to the server.
  5. Once I get the passcode, I use it to decrypt the info from my database, and send the decrypted info back to the browser.

Bottom line is that, I never store the passcode used as the key for the encryption. Now this is going to sound naive and broad, but can someone give me an idea of whether/how secure this procedure would be? My guess is that, since the key is nowhere to be found on the server, the info is as secure/insecure as the AES encryption method itself.


How to encypt sensitive data in database of a web app?

I've been reading answer from the above link, which involves a several additional layers of encryption. I can probably implement it, but are those additional steps necessary for my purpose? And if so, how did those steps make it more secure than what I have described above? For example, worst-case scenario, if the entire server is compromised, would this latter method be more desirable?

Thanks!

  • Someone could maybe make a better answer than me, so I'll just give you a comment. What you suggest is OK. The link you give is a better way to do it, because (1) you can easily handle the encrypted data (for example when users change their password) and (2) it uses a PBKDF to avoid brute-force attacks. There are multiple ways (encryption modes) to use AES, some of them insecure. In your case, AES-CTR would be a good choice. Maybe you need to also authenticate your encrypted data, in this case, please edit your question or ask another one. – A. Hersean Oct 22 '18 at 07:43

2 Answers2

-1

I think one main problem for the first approach is that once the passcode is lost by the user, there is no way at all to ever recover it (without brute-force). Depending on the kind of information that might be a requirement though.

So coming to the linked article it will explain how it solves that problem. It has more comfort and lets you implement it in the hopefully already existing change password algorithm to always generate a new KEK and re-encrypt the DEK. The password is more unlikely to be forgotten

Nico
  • 509
  • 1
  • 4
  • 12
-2

You have two problems:

1) If you use a key generated from password to encrypt user's data, you will need to decrypt and encrypt data all again if user resets his/her password.

Solution: Use the approach proposed in the link you posted (DEK and KEK).

2) It is common that users forget their passwords especially if they don't login so often and data decryption always depends on the password.

Proposed solution: Use something that users hardly forget, i.e. their email addresses.

Encrypting:

  1. Ask users to enter their email address
  2. Concatenate email address with a salt and hash them to generate a key that will be used to encrypt the password
  3. All this should be done in the user side (not server side)
  4. You keep the salt and the encrypted password in your database (you should not keep their emails, or can you?)

If the user forgets his/her password:

  1. Ask the user to enter their email address
  2. Verify ownership of the email address by sending a verification email
  3. Use the email address along with the salt you have to re-generate the key used to decrypt the password.

You don't want to generate KEK from email address because you will always need to verify the ownership of email every time user logs in your web app.

schroeder
  • 125,553
  • 55
  • 289
  • 326
daygoor
  • 138
  • 6
  • 1
    In your scheme number 2, the server has all the needed data to decrypt the users' sensitive information. – A. Hersean Oct 22 '18 at 07:30
  • 1
    "something that users hardly forget" is also something that non-authorised people would also know. This is the same problem as "what is your mother's maiden name?" That's why passwords need to have some level of uniqueness. Emails, though, is a very, very poor example, especially if you ask for it directly. – schroeder Oct 22 '18 at 08:38
  • the web app is using email address and salt to generate a key but it is not keeping the email address! He can also use mobile number @A.Hersean – daygoor Oct 22 '18 at 08:49
  • He is not using the email as password .. never said that in the answer! read carefully! Email + salt is a combination used for encrypting the real password used for login and encrypting data. Email known by user and salt known by server! @schroeder – daygoor Oct 22 '18 at 08:51
  • Please read again schroeder's answer. The user's email is a public information, it is not a secret. – A. Hersean Oct 22 '18 at 08:53
  • I did read carefully. Your process makes no sense and you contradict yourself, so your process end s up being to use the email as the password. " If user forgets his/her password ask them to enter his/her email " "use the email address along with the salt you have". – schroeder Oct 22 '18 at 08:54
  • You have two weaknesses here: using the email as a Key, and performing all salting and hashing client side (which then has to be stored client-side? This part is all confused). You either intend to use the email as a password, or you create a random password (using email, and client-side stored salt) which you do not salt on the server side, which means it ends up just like a plaintext password in your database. Either way, the server has all info it needs to decrypt without ever needing to ask the user for interaction. – schroeder Oct 22 '18 at 08:57
  • User will enter email address but he will not be given SALT unless he verify the ownership of the email and that's by using verification email @schroeder – daygoor Oct 22 '18 at 08:57
  • I edited your answer to highlight the steps. So, you are now saying that the salt is *not* generated client-side, but server side? If so, then the email address is most certainly the password – schroeder Oct 22 '18 at 09:05
  • But the salt is a server-side mangle. Just like every other password. What the user provides the process is just the user's email. – schroeder Oct 22 '18 at 09:07
  • Email address and salt are the password. Server does not store emails (if server requires storing email then server can use mobile number instead). Attacker doesn't know salt unless he gets into the database. The only way to recover original password is to request email address or mobile number, verify ownership and then fetch the corresponding salt in the server! If that is bad practice then I don't know how you can recover a secret password or secret DEK without storing all information about them in the server. @schroeder – daygoor Oct 22 '18 at 09:19
  • When logging into any site, you do not know the salt. And you don't have to, because that's handled server side. All you provide is the password. You have the exact same set up here. All the user provides and all the user needs to know is an email. Email is the password. And, as I said, if you take the original password (email or whatever), salt and hash it client-side, then store that, then the hash is the password, sent and stored in plaintext. You just created a plaintext password (the attacker doesn't need to know the password or the salt, they just need this hash). – schroeder Oct 22 '18 at 09:28
  • Isn't that the point though @schroeder? We are trying to protect the encrypted personal data inside the database from attackers and unauthorised access from server side. The data are encrypted using DEK, DEK is encrypted using KEK, KEK is generated using password, password is only known by user. If user forgets password, server still have encrypted version of it. It is encrypted using a salt that severs&client only knows and an email/mobile that server doesn't know! – daygoor Oct 22 '18 at 09:57
  • "password is only known by user" - not if the password is public information (email, phone number) – schroeder Oct 22 '18 at 09:58
  • Please look up the various questions on this site that deal with the weaknesses of performing salting and hashing client-side. – schroeder Oct 22 '18 at 10:00