SHA Hash Issue
July 7, 2008 5:02 PM   Subscribe

Is there a way to convert between two different types of SHA Hashes?

Hey there..I am pretty sure I'm going to be S.O.L. here, but I thought I'd ask anyway. My DB is storing our users passwords in a SHA256 Hash. I need to also access a database that is storing the same passwords in a SHA1 Hash. The application is written in C# and I can convert the passwords into SHA1 and SHA256 no problem but...
My database(256) already has a bunch of passwords stored and we need to populate the other database(1) with these passwords in the other Hash format.
So..Is there a way to take a password stored as a SHA256 Hash and convert it to a SHA1 Hash? Or am I about to reset all of the passwords in my system to accommodate accessing this other database which is using the different hash algorithm.
posted by smithygreg to Computers & Internet (10 answers total)
 
You are, in fact, SOL. To "convert" the hash, you'd need to know how you got there, which means having the original password, which means... you're SOL.

Since the hashes are of different length, you could, I suppose, just store them all as-is and verify each type of password differently, depending on the length of its hash. But you probably don't want to do that.
posted by Tomorrowful at 5:15 PM on July 7, 2008


Good lord I hope not! The point of SHA and hash functions in general is that it is computationally infeasible to find a message that corresponds to a given message digest.

You could, I guess, rehash the legacy SHA1 passwords into SHA256, store them, then in the password-checking code try SHA256(SHA1(plaintext)) if SHA256(plaintext) doesn't match the stored password hash. Not the classiest solution in history but it would work and still be reasonably secure.
posted by nicwolff at 5:20 PM on July 7, 2008 [1 favorite]


Yeah, definitely not. Hashes are (ideally, generally) one-way. It can't "undo" the hash and then redo it as another SHA; to do so would represent a huge fail in the hash.

Nicwolff's suggestion is a good one. It's not a great idea, but you can just "double-hash" the input for legacy passwords to get the input into the state that your passwords will now be stored as.
posted by disillusioned at 5:24 PM on July 7, 2008


Since the hashes are of different length, you could, I suppose, just store them all as-is and verify each type of password differently, depending on the length of its hash. But you probably don't want to do that.

And ironically, this is actually how Windows user passwords are stored. One version is a weak Lan Manager hash for backwards compatibility, and another is a newer more secure hash. The system as a whole is only as secure as the weaker hash, so yes, you don't want to do this.
posted by smackfu at 5:34 PM on July 7, 2008


Just add the dual functionality to your login process and put up a note that says something like "We are upgrading our security, please re-enter your password" and regenerate (or cut over) your hashes that way. Add a check to see if the SHA256 hash exists in the DB and your users will only see it once.
posted by rhizome at 6:17 PM on July 7, 2008


If you're not salting the hashes, and literally just doing H(password), you can probably quite easily break them using pregenerated rainbow tables. So yes, you might be able to convert your SHA256's to SHA1's, but this will be a sign you need a third password format to migrate the other two to ;)
posted by Freaky at 7:16 PM on July 7, 2008


Best answer: Just calculate the other hash when the user logs in the next time. And if your sessions don't time out, maybe now would be a good time to change that :)
posted by sergent at 8:19 PM on July 7, 2008


Freaky - I've never used SHA256 but I'm assuming SHA256 is many to one, in which case rainbow will only give you one possible route to the password. I'm guessing that the SHA256 could be rainbowed out to either A or B and that A and B will have different SHA1 values.

Maybe I'm missing something... If you want to make them all SHA1 then why not just go through the whole table changing OLDPASS to SHA1(OLDPASS.SEED)? Then when someone logs in, instead of checking for SHA256(PASS) you check for SHA1(SHA256(PASS).SEED)?

It's slower, but it's not as insecure as it could be...

Failing that, something like this...?
get storedpass
if (sha1(pass)==storedpass) login
elseif(sha256(pass)==storedpass) update DB so storedpass = sha1(pass); login
else toughluck
posted by twine42 at 1:21 AM on July 8, 2008


Damnit... in my 'failing that' code, the sha1(pass) should be sha1(pass.seed). Seeds are good. Even if it's something stupid like the servername, then it's enough to stop a prefab rainbow table being of any use to anyone.
posted by twine42 at 1:24 AM on July 8, 2008


I'm guessing that the SHA256 could be rainbowed out to either A or B and that A and B will have different SHA1 values.

It could be, but it's overwhelmingly more likely to actually give you the password if it finds it. You'd be better off wondering what you're going to do when you become a billionare after winning the $300m Powerball lottery jackpot 4 times in a row.

The way we did password hash migration was to keep support for old hashes, and on a successful authentication, update them. After a while, when everyone's populated the new columns, you can drop support for the old hashes.
posted by Freaky at 2:17 AM on July 8, 2008


« Older Why is my penis falling asleep?   |   I promise this is the last computer question I'll... Newer »
This thread is closed to new comments.