I'm developing a desktop application where the users will login with username and password, which is then verified against a database. After the initial login, the current user should be automatically logged in each time the application is started (until the user logs out or 1 month has passed).
I could encrypt and store the last successful username and password on the computer, but the decryption key would have to be known by the application and hence possible to extract. I could use the Windows Data Protection API to store the credentials, but I might need to support other platforms so I would rather not. Storing the hashed password (same as in the database) on the computer is not safe, since a malicious user with read access to the database could replace the username and hash on the computer with another user's data from the database.
So, my plan is this...
Create user account
- Generate random salt
- Hash the initial password twice using
argon2id(argon2id(password, salt), salt)
- Store username, salt and hashed password in the database
User login
- Read user's salt from the database
- Calculate
hash1 = argon2id(password, salt)
- Calculate
hash2 = argon2id(hash1, salt)
- Check that hash2 is equal to the hash stored in the database
- If successful, store hash1 on computer
Restart application
- Read user's salt from the database
- Read hash1 from computer
- Calculate
hash2 = argon2id(hash1, salt)
- Check that hash2 is equal to the hash stored in the database
This way, neither the plaintext password nor the hash used for verification in the database is stored on the computer. But since the general advice regarding encryption and hashing is "don't roll your own", I wonder if there is some better method that I have missed - or if there is some serious drawbacks with my method? (I'm probably overthinking this since the application is for internal use only and the data is not sensitive either - top notch security is not required.)
I do see the problem that the stored username and hash1 can be stolen from the computer but that will be covered by operating system security.
I have read about layered hash shucking but since the inner hash is both salted and using a modern hash algorithm, I don't think that will be a problem.
Is there a problem with reusing the random salt for both the inner and outer hashes?