3

An application used by multiple users is accessing the database directly (so a potential attacker could also access the database directly).

On application startup, user authenticates using username and password.

Each user has its own key pair. This key pair MUST be stored in the database.

Question:

While keeping the scenario described above in mind:

Is there is a better way than encrypting the private key using a key derived from users password?

1

Provided you are properly using a NIST-approved authenticated encryption mode (such as AES-CBC & HMAC-SHA with proper KDFs & IVs, e.t.c.) breaking this should be as difficult as simply breaking an encrypted file. Now, depending on your use case this could/could not be enough. I will take you through a couple of other options I myself can think of, as well as the potential security benefits/drawbacks it may offer.

Option 1: Standard authenticated encryption with encrypted private key stored in DB

This (as mentioned before) will be security-wise just as good as encrypting a file in the same way, and should be as hard to break as the underlying encryption. However, it offers one major drawback: this allows an attacker to destroy/irreversibly modify the private key data, because this simply is not part of the encryption threat model (it only cares that the data is secret and cannot be modified without being detected). This is where I propose solution no.2:

Option 2: DERIVE the private key using the user's password

This option is involves (basically) feeding your derived key into a PRNG and generating the private key every time (whenever you need the private key, you just derive it from the user's password), this has the advantage of

  • not even being stored in the database,
  • the private key (obviously) cannot be corrupted now, because it is not stored anywhere.

However, this option may be a little more risky than option 1 because of two reasons:

  • PRNGs are generally considered inferior in terms of security to block ciphers (such as AES)
  • Depending on your choice, a brute-force attack on the underlying password MIGHT be faster than trying to break AES
  • The number of possible private keys is now inevitably much shorter (due to the nature of a psuedorandom number generator).
  • Users public key is used to encrypt one or multiple (symmetric) content keys. So user can decrypt the content key(s) using the private key. When using option 2, on password change, it's requires to decrypt all content keys using the key derived from old password and encrypt the content keys using the key derived from new password (alternative solution: use an intermediate key – which must be stored in database...). Using option 1, it’s just required to encrypt the private key with new key derived from new password. So all in all option 1 is the better choice. Or am I missing somthing? – Ratlos Feb 5 '18 at 16:37
  • @Ratlos, option 1 definitely makes much more sense. I was also trying to create an option 3 based on some kind of weird decentralization, but after analysis realized it yields no apparent security benefit and is pretty messy, so as it seems in your particular case (with no content stored on the user's machine -- offline) option 1 is both the one with a highest security guarantee & likely no worse in terms of practicality. – Samuel Allan Feb 5 '18 at 22:40
  • @Ratlos, also: Option 2 (while yielding theoretical indestructibility of the private key), however, also has the problem that anything encrypted with it (stored in the database) can simply be destroyed directly, so really in this case option 2 makes very little sense. – Samuel Allan Feb 5 '18 at 22:42

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.