Cryptography/Software Engineering Problem: How to make LW 1.0 logins work on LW 2.0
So, as part of making the transition to LessWrong.com smooth, I’ve been working on trying to get the old passwords to work on the new site. Now I want to be very careful with this, since it’s super easy to mess up crypto and I have no interest in leaking everyone’s private info from the old site (or messing up authentication for the new site)
The current situation is that we have the old password hashes (SHA1 hashes) from the LW 1.0 database, as well as their corresponding salts. And we are running on the Meteor Accounts system on the new page, which uses bCrypt for hashing.
The Meteor accounts system is designed so that you can’t really override any of its login procedures, probably to avoid users shooting themselves in the foot. Meteor also hashes the passwords on the client, so on the server we have no access to what password the user typed into the password field. This puts us into a bit of a dilemma about how to deal with the old passwords.
So to summarize, we have the following variables:
lw1_hash_function(password, salt); lw_1_password_hash(user); lw_1_password_salt(user); authenticate_lw2_client(plaintext_password); authenticate_lw2_server(password_hash); set_lw2_password(plaintext_password, user)
Besides setting passwords, these are really all the functions we can access. Now, there is one thing we could do that would work, but that seems like a somewhat hacky solution to me, so I wanted to get input from people who are better at crypto than me:
First, we set everyone’s password to be equivalent to their old LW1 hashes (i.e. they could log in if they would type in their old LW1 password hash into the password field). This means their original plaintext password would now have gone through two hashing functions, once the LW1 hash function, and then again through the LW2 hash function.
Then when the login request arrives on the server, we check whether the user is using one of the old LW1 accounts, and if they do, we send back an error to the client (and this is where I am hesitant), together with the
lw_1_password_salt for the user they are trying to login with. On receiving that error, the client uses the old lesswrong hash function (
lw1_hash_function()), and combines the password they just typed in with the salt they just received, and then tries to login again with the resulting hash (which would now succeed for legacy users).
A quick prototype I’ve hacked together for this seems to work, but the part I am hesitant about is to release the salt of the original user to whoever is trying to login into that user’s account.
It seems that at least a few other authentication systems seem to do something like this, and from my best understanding it is not important for salts to be secret and doing so does not improve security in any significant way. But this seems exactly like the kind of thing you would want to run by a bunch of people with more crypto expertise, so this is me doing that.