Password hashes were the hobby horse that first convinced me to get
involved in MediaWiki programming, back in 2003. Here's my outraged post:
http://marc.info/?l=wikitech-l&m=104904771815534&w=2
The relevant code was the first code I wrote for MediaWiki. Looking back
now, my immaturity as a programmer at the time shows through, and if
someone tried to submit something similarly naive today, I'd hope that
we'd have a few senior developers around (e.g. me) to point out its
problems and send it back for a rewrite.
The idea was to use md5($userId.'-'.md5($password)) as a hash. This has a
number of problems:
* There's no way to tell whether a hash is in the old style or the new
style. So migration is difficult and error-prone.
* The migration issues will be repeated every time we have to change hash
functions, which might be every decade or so due to improving
cryptanalysis and computing power.
* It links the password to the user ID, making it impossible to transfer
passwords from one user to another.
* The salt always has the same value on single-user wikis (1), so it's
insecure.
The obvious solution is to attach the salt to the hash. Luckily
user_password has been a tinyblob since the dawn of time, so we're not
space-constrained. We could store the salt in a different field (like
what's done in CentralAuth), but that wouldn't solve quite so many of the
problems listed above.
So I've committed a hash format change, so that salted hashes look like this:
:B:a2a5c3b9:44ebabb085ce78dd20c2d59c51e4080c
That is, a type "B" hash, with salt "a2a5c3b9" and MD5 hash
"44ebabb085ce78dd20c2d59c51e4080c". The way the salt and the password are
mixed together is the same as in the old system, so you can migrate to
this password format simply by prepending :B: and the user ID.
Unsalted hashes look like this:
:A:d41d8cd98f00b204e9800998ecf8427e
Password hashes will be migrated to the :A: or :B: style on upgrade, and
after that, you'll be able to switch $wgPasswordSalt on and off at will,
and all passwords will continue to work. Before upgrade, the software will
understand the old-style hashes, but it requires $wgPasswordSalt to be set
correctly.
When we eventually migrate from MD5 to Tiger/192 or whatever, we can
introduce a type "C" hash and then convert the old hashes at our leisure.
This change has been on my mind for a while, but the immediate motivation
is bug 14330.
-- Tim Starling