I was reading "A Convenient Method for Securely Managing Passwords, Halderman et al., 2005". In short, the authors say to do the following:
cache = very_long_key_derivation_function(salt,master_password)
save the cache on disk
password_for_site_a = short_key_derivation_function(salt,site_a|master_password|cache)
password_for_site_b = short_key_derivation_function(salt,site_b|master_password|cache)
where
- very_long_key_derivation_function is some key derivation functions tuned to require approx 2 minutes
- short_key_derivation_function is some key derivation functions tuned to require 1 second.
This forbids to site_a to brute force the secret in order to find the password of site_b (since each try requires 2 minutes), still allowing fast time to calculate the password of a website. If the cache file is stolen, is still necessary to guess the master_password to know the derived passwords.
There are two problems with this method:
- the master_password is used each time the user needs the password of a certain site
- in order to change the master password (it is used often, it could be seen), all the derived passwords must be changed
I would like to modify the schema in the following way:
k1 = very_long_key_derivation_function(salt,master_password_1)
k2 = short_key_derivation_function(salt,master_password_2)
cache = k1 xor k2
save cache on disk
password_for_site_a = short_key_derivation_function(salt,site_a|(cache xor k2))
password_for_site_b = short_key_derivation_function(salt,site_b|(cache xor k2))
In this way master_password_1 is used only once (the first time the password manager is used), while master_password_2 is used each time the user needs a password for a site. The derived passwords do not depend on master_password_2. Assuming that master_password_1 can not be stolen (since it is used only once), in order to steal a site password both the cache file and master_password_2 are needed. Also, it is possible to change master_password_2 if the user suspects that somebody saw him writing it, by computing:
k1 = very_long_key_derivation_function(salt,master_password_1)
k3 = short_key_derivation_function(salt,master_password_3)
cache = k1 xor k3.
save cache on disk
when the user will use master_password_3 the derived site passwords will be the same as before.
I would use some string derived from the username as a salt, and argon2 as key derivation function. Do you think this could be a good method to manage passwords?