1
$\begingroup$

I'm designing a system in which a password is used both for logging in as well as for encrypting some payload.

To encrypt a payload I derive a key from the password. Very straightforward so far.

Since that encryption should be end to end, the password is not sent to the server, but it is hashed first and then sent to the server. The server then re-hashes that password to store it in the database (for the same reason you hash a password).

It is paramount that the server cannot rebuild the password not the password-derived key that was used to encrypt the payload.

So, my question is about which algorithms to chose for each of these instances.

I'm pretty sure that to hash the password for authentication purposes I want to use Scrypt. I'm aware it hasn't been tested long enough but it seems to be offering the best security these days.

To derive the key from the password, my plan was to use PBKDF2. Reading about it, some people do recommend to use Scrypt instead of PBKDF2 as it's more resilient to GPU attacks. My problem with doing that is that if I use Scrypt for both, auth and key derivation, I could be exposing the key to the server (during authentication).

How should I resolve that problem other than by using two different algorithms?

For the record, for encryption I'm using AES, specifically, AES/GCM/NoPadding, although this is not set in stone.

My implementation is done in Java and currently I'm using Bouncy Castle.

$\endgroup$
2
  • $\begingroup$ It seems what I'm after is HKDF, which has an extra info argument to generate different keys from the same secret: en.wikipedia.org/wiki/HKDF $\endgroup$ Aug 31, 2017 at 15:51
  • $\begingroup$ yes, generate bytes equal to length of both keys, and use first half as one key and remaining as second? $\endgroup$
    – crypt
    Aug 31, 2017 at 19:31

1 Answer 1

1
$\begingroup$

My problem with doing that is that if I use Scrypt for both, auth and key derivation, I could be exposing the key to the server (during authentication).

If you use two hashes then one failing breaks whole system. Using one reduces chance of being broken than using two.

I'm pretty sure that to hash the password for authentication purposes I want to use Scrypt.

Scrypt isn't a hash, it is PBKDF. PBKDF2 is also a PBKDF, not a hash.

How should I resolve that problem other than by using two different algorithms?

First of all, don't use two different PBKDFs. Then you have two different attack vectors, and you spend less time per PBKDF than with one strong PBKDF.

You should derive master key first, using some PBKDF (I would recommend Argon2, making sure strong settings are used and using salt). After master key is derived you should use KDF (Key Derivation Function) to do exactly what you ask for: Make two keys from one. Then you have K1 and K2. K1 can be used for encryption and K2 can be sent to server which also should hash it(PBKDF is useless there).

You should also consider if server should store salt (+you can access your data after HDD fail; -Server can try to break your password).

$\endgroup$
4
  • $\begingroup$ How do you derive two different keys using the same algorithm from the same starting key, so that they are different (and don't help getting at the other one)? $\endgroup$ Aug 31, 2017 at 10:55
  • $\begingroup$ @Pablo I already answered that KDF is designed to do that. $\endgroup$
    – axapaxa
    Aug 31, 2017 at 14:37
  • $\begingroup$ Yes, but KDF is a concept, not an algorithm. My question was to try to find what algorithm I should use for KDF. $\endgroup$ Aug 31, 2017 at 15:31
  • $\begingroup$ @Pablo HKDF with Sha3/Blake2 for KDF and Argon2 for PBKDF would be my choices. Also this steers outside of your question scope, so don't ask me why :). $\endgroup$
    – axapaxa
    Aug 31, 2017 at 18:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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