We are setting up a web application which requires users to submit sensitive data. Since entering all the required data may take a long amount of time, we want to give them the option to save their progress. Maintaining a database to store their information is risky for us, as it opens up our servers to potential attacks. We have a small team and would be hard pressed to maintain the level of security we would want.

Rather than maintaining such a database, we would like to encrypt the user's partial progress (a text string in JSON format) with a password that we provide and that is supplied to them only at the time they wish to save progress. They will be instructed in the UI to physically write the password down rather than save it on their computer. To resume progress, they would supply us the encrypted file and the password. On our end, no data is persisted. If they lose the password they just have to start again.

Is any portion of this method obviously insecure? What encryption algorithms and libraries (Java or Python) are best for performing encryption/decryption?

  • $\begingroup$ Where are you keeping the password that you gave the users? delete it or keep it? How you generate the passwords? How you send the password to them? Did you use any Key Derivation functions as PBKDF2 or Argon2 to generate the encryption keys?.... $\endgroup$ – kelalaka Jan 13 '19 at 19:00
  • $\begingroup$ We are not keeping the passwords. When resuming a session they will be prompted to enter a password which we will use to decrypt. (This implies that authentication must be part of our encryption protocol). $\endgroup$ – mkreisel Jan 13 '19 at 19:02
  • $\begingroup$ Password generation is an open question. We could prompt them for a password or provide one ourselves. It seems that generating passwords would be more secure, however if I'm wrong then please explain. If you have suggestions for how the password should be generated then that would be very helpful for me. $\endgroup$ – mkreisel Jan 13 '19 at 19:04
  • $\begingroup$ authenticated encryption tag is not what you understand. $\endgroup$ – kelalaka Jan 13 '19 at 19:05
  • $\begingroup$ @kelalaka If we supply the password then it will be provided in a window in the browser. We have not implemented this yet (which is why I'm asking) so we can use such functions to generate encryption keys if that is the recommended best practice. $\endgroup$ – mkreisel Jan 13 '19 at 19:05

This answer proposes a solution based on local storage and local encryption.

The data of the forms that the user enters:

  • Can be locally encrypted whenever the user wants to save...
  • The encrypted file(s) can be stored locally, if you want to store it to, you can transfer a copy to your server
  • The encrypted file(s) can be decrypted locally and restored into forms by JScript. You can use NodeJS.
  • If the user lost their file(s) then if you saved in your server, you can transfer back to the user to resume.

The methods;

  • From a password to an encryption key, you can use PBKDF2. Ask the user to a good password to increase against the brute-force attacks.
  • For encryption of the data, you can use AES-CBC with randomly generated IV. If you want to authentication for the encrypted data, you should, you can use AES-GCM.

Don't forget to ask the user to write the password at somewhere.

|improve this answer|||||
  • $\begingroup$ Note that NodeJS is not actually a local solution. Node runs on the web server itself, not in the browser. $\endgroup$ – mkreisel Jan 13 '19 at 20:33
  • $\begingroup$ @mkreisel The server only supplies the code. stackoverflow.com/questions/17933696/… $\endgroup$ – kelalaka Jan 13 '19 at 20:41
  • $\begingroup$ is there any advantage to running encryption in the browser rather than sending the password over TLS and handling encryption in the back end? In the back end we have more control over the environment running the crypto algorithms. $\endgroup$ – mkreisel Jan 13 '19 at 23:21
  • $\begingroup$ That is another solution that I did not mention since you don't want to store. There are differences, the user can choose a different password that the server never knows. The data needs to be sent the server then back to the user to encrypt and later for decrypt, too. $\endgroup$ – kelalaka Jan 13 '19 at 23:33
  • 1
    $\begingroup$ Maybe, you should delete this question and re-write and ask at information security? $\endgroup$ – kelalaka Jan 13 '19 at 23:50

Regardless of the password, encryption, etc., you have another possible issue. You will need to make sure that, when you receive the decrypted JSON object(s), you again validate them to make sure they have not been tampered with while in the possession of the user.

Whether such an attack is worth doing will depend on the application (think game server, scores and current level, for instance). But even if the user gains nothing, if you look up "deserialization" as a security problem, you'll have some understanding of this problem, and will be able to decide how much to trust the received JSON on a "resume".

I realise this is not "crypto"; apologies for that but I thought it was relevant to the spirit of the question.

|improve this answer|||||
  • $\begingroup$ Do you mean that after decryption, the front end should validate that the resulting text is valid JSON with a particular format? $\endgroup$ – mkreisel Jan 22 '19 at 16:31
  • $\begingroup$ yes but not just "valid JSON"; depending on the application you may even have to add some integrity checks to ensure the user cannot even change what you stored, even if the result is valid JSON. $\endgroup$ – sitaram Feb 13 '19 at 13:35

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.