# Why does LastPass hash their passwords with PBKDF2 this way?

LastPass is a password manager that I am sure many of you are familiar with. I have been studying LastPass's source code a bit. From their FAQs and what I can gather from their source code, the way they derive and store your encryption key is as follows:

The resulting encryption key is used for encrypting and decrypting your vault information.

For the purposes of authentication with their servers, they then take that encryption key and hash it using PBKDF2 again, this time using the previously generated encryption key as the password input and the user's master password as the salt. This is done with just 1 iteration.

The resulting hash is then transmitted to the LastPass servers where (according to their FAQs since I cannot see their server source code) they again use standard PBKDF2 with a random salt and 100,000 iterations.

# Pseudo code

pbkdf2(algorithm, password, salt, iterations, bytes)


Client

enc_key = pbkdf2(sha256, master_password, email, client_iterations, 32)
key_hash = pbkdf2(sha256, enc_key, master_password, 1, 32)


Server

stored_hash = pbkdf2(sha256, key_hash, random_bits, 100000, 32)


# Questions

I am confused about the key hashing process that they are doing. It appears that they are using PBKDF2 as a means for computing a SHA256 hash to protect it during transmission to their servers.

• Can you explain what using PBKDF2 with 1 iteration is doing in the above?
• Is this the same as just doing something like a HMAC SHA256 hash?
• Are there any concerns with something like a compromised server receiving this hash and being able to derive anything from it about the original encryption key or master password (prior to the stored hash being computed)?
• I wish all questions were asked that nicely! Good work on explaining what your question is :) – axapaxa May 18 '17 at 17:44

Can you explain what using PBKDF2 with 1 iteration is doing in the above?

Is this the same as just doing something like a HMAC SHA256 hash?

This is mostly HMAC-SHA256, but you can declare how many bits of derived key you want. I assume it is used this way for ease of implementation (it's easier to have one working implementation of PBKDF2 than many primitives arranged in complex way).

Are there any concerns with something like a compromised server receiving this hash and being able to derive anything from it about the original encryption key or master password (prior to the stored hash being computed)?

No, this is nearly impossible to do because as long as SHA256 is one way. It is very unlikely that SHA256 will be broken in such way (MD5 and SHA-1 have collision attacks only). If anything, this will leak if password was changed, because there is no random part added before it is sent to server, which is design flaw (unless they do something extra which you omitted).

Also, as SEJPM noticed, it is weird that only 5k iterations are done on user device and 100k iterations on their server. This would put server in better position to perform a brute-force attack. However, 5k iterations on client seem very low for most computers, and probably should be adjusted anyway.

• Note though that this approach puts the server into a position to speed-up the brute-forcing of the password by a factor of about 20 by default (as he can brute-force the 5k iteration hash rather than the 105k iteration one). Of course this only chops a little bit more than 4 bits off the password's security margin... Oh and the idea behind this server-involvement is probably to prevent off-line brute-forcing (due to the salt being secret) and that they maybe try to enforce some form of rate-limiting (both of which assume a trusted server of course...). – SEJPM May 18 '17 at 18:01
• Any idea why the master password is used as the salt? Seems kind of weird. Could email address have been used just as securely? – izzle May 18 '17 at 18:09
• @SEJPM oops, I didn't notice they did 100k iterations on server, added note on that, Thanks! As for why they use master password as salt later on - no idea, but it's very unlikely that this changes anything. – axapaxa May 18 '17 at 18:35
• "If anything, this will leak if password was changed, because there is no random part added before it is sent to server, which is design flaw". You mention that this is a design flaw. How could they add a random part to it? Isn't the whole point of a hash that it computes to the same value each time? How else would they verify the authentication against what is stored? – izzle May 19 '17 at 2:49
• @izzle you can derive hmac-sha256(stored_hash,rng) on both sides: client and server. Server will still need to learn stored_hash at first, but then you can only send derived value, along with rng value. If rng was derived by server and client you can prevent replay attack. There also is way to make server unaware of client password change (perform correct xor on changing password so key_hash stays same). One thing you lose then is random_bits being private, but if we don't trust server then it gives more security to client. – axapaxa May 19 '17 at 9:58