Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Wikipedia: Wikitech

Password hash format

 

 

Wikipedia wikitech RSS feed   Index | Next | Previous | View Threaded


tstarling at wikimedia

Jun 5, 2008, 5:07 AM

Post #1 of 8 (6565 views)
Permalink
Password hash format

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


_______________________________________________
Wikitech-l mailing list
Wikitech-l [at] lists
https://lists.wikimedia.org/mailman/listinfo/wikitech-l


nospam at vyznev

Jun 5, 2008, 9:13 AM

Post #2 of 8 (6455 views)
Permalink
Re: Password hash format [In reply to]

Tim Starling wrote:
>
> 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.

While we're at it, why not introduce some form of adjustable key
strengthening:

http://en.wikipedia.org/wiki/Key_strengthening

For example, we could store the hashes like this:

:C:65000:e2a6fb36:37860b819a5e8e71538370316f06a8db

where 65000 is the number of times to iterate the statement $hash =
md5($hash . $salt . $password) to compute the hash (starting with $hash
= ""). The value for new passwords would be set through a config
variable (e.g. $wgPasswordIterations), with old records updated to use
the current iteration count on login.

--
Ilmari Karonen

_______________________________________________
Wikitech-l mailing list
Wikitech-l [at] lists
https://lists.wikimedia.org/mailman/listinfo/wikitech-l


tstarling at wikimedia

Jun 5, 2008, 9:51 AM

Post #3 of 8 (6456 views)
Permalink
Re: Password hash format [In reply to]

Ilmari Karonen wrote:
> Tim Starling wrote:
>> 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.
>
> While we're at it, why not introduce some form of adjustable key
> strengthening:
>
> http://en.wikipedia.org/wiki/Key_strengthening
>
> For example, we could store the hashes like this:
>
> :C:65000:e2a6fb36:37860b819a5e8e71538370316f06a8db
>
> where 65000 is the number of times to iterate the statement $hash =
> md5($hash . $salt . $password) to compute the hash (starting with $hash
> = ""). The value for new passwords would be set through a config
> variable (e.g. $wgPasswordIterations), with old records updated to use
> the current iteration count on login.

Well, I did consider it, back in 2003, the tradeoff of course is speed.
Because we're working in PHP, an attacker could do the same operation
several times faster than we could, using C/C++. Serving web pages is
meant to be fast, with lots of concurrent requests, and there might be a
need to do batch operations. There's probably an argument for stretching
it out to a few milliseconds, but with 65000 iterations I get 130ms on
zwinger which is probably going a bit too far.

-- Tim Starling


_______________________________________________
Wikitech-l mailing list
Wikitech-l [at] lists
https://lists.wikimedia.org/mailman/listinfo/wikitech-l


gmaxwell at gmail

Jun 5, 2008, 10:07 AM

Post #4 of 8 (6458 views)
Permalink
Re: Password hash format [In reply to]

On Thu, Jun 5, 2008 at 12:51 PM, Tim Starling <tstarling [at] wikimedia> wrote:
> Well, I did consider it, back in 2003, the tradeoff of course is speed.
> Because we're working in PHP, an attacker could do the same operation
> several times faster than we could, using C/C++. Serving web pages is
> meant to be fast, with lots of concurrent requests, and there might be a
> need to do batch operations. There's probably an argument for stretching
> it out to a few milliseconds, but with 65000 iterations I get 130ms on
> zwinger which is probably going a bit too far.

While you are taking requests:

JS SRP please: http://code.google.com/p/clipperz/source/browse/trunk/crypto.library/src/js/Clipperz/Crypto/SRP.js

(http://en.wikipedia.org/wiki/Secure_remote_password_protocol)



:)

_______________________________________________
Wikitech-l mailing list
Wikitech-l [at] lists
https://lists.wikimedia.org/mailman/listinfo/wikitech-l


brion at wikimedia

Jun 5, 2008, 11:35 AM

Post #5 of 8 (6470 views)
Permalink
Re: Password hash format [In reply to]

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Tim Starling wrote:
> 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

Ahh, the good old days... :D

> 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.

Awesome!

> This change has been on my mind for a while, but the immediate motivation
> is bug 14330.

Indeed; this nicely solves the problem of migrating passwords across
wikis... applicable to other potential "merge multiple wiki" sort of
tasks as well, if needed.

- -- brion
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkhIMfIACgkQwRnhpk1wk461IQCfdP35ZYiX4eJERL2V0l6lcMNV
RzkAnilxbHY1nivMTtVSAYmlzUUJmDmn
=UJ5J
-----END PGP SIGNATURE-----

_______________________________________________
Wikitech-l mailing list
Wikitech-l [at] lists
https://lists.wikimedia.org/mailman/listinfo/wikitech-l


Simetrical+wikilist at gmail

Jun 5, 2008, 11:52 AM

Post #6 of 8 (6455 views)
Permalink
Re: Password hash format [In reply to]

On Thu, Jun 5, 2008 at 1:07 PM, Gregory Maxwell <gmaxwell [at] gmail> wrote:
> While you are taking requests:
>
> JS SRP please: http://code.google.com/p/clipperz/source/browse/trunk/crypto.library/src/js/Clipperz/Crypto/SRP.js
>
> (http://en.wikipedia.org/wiki/Secure_remote_password_protocol)

That implementation is AGPL v3, seemingly. What are the issues with
combining that with MediaWiki? The AGPL v3 is compatible with GPL v3,
but not GPL v2.

_______________________________________________
Wikitech-l mailing list
Wikitech-l [at] lists
https://lists.wikimedia.org/mailman/listinfo/wikitech-l


jared.williams1 at ntlworld

Jun 5, 2008, 5:16 PM

Post #7 of 8 (6465 views)
Permalink
Re: Password hash format [In reply to]

> -----Original Message-----
> From: wikitech-l-bounces [at] lists
> [mailto:wikitech-l-bounces [at] lists] On Behalf Of
> Tim Starling
> Sent: 05 June 2008 17:52
> To: wikitech-l [at] lists
> Subject: Re: [Wikitech-l] Password hash format
>
> Ilmari Karonen wrote:
> > Tim Starling wrote:
> >> 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.
> >
> > While we're at it, why not introduce some form of adjustable key
> > strengthening:
> >
> > http://en.wikipedia.org/wiki/Key_strengthening
> >
> > For example, we could store the hashes like this:
> >
> > :C:65000:e2a6fb36:37860b819a5e8e71538370316f06a8db
> >
> > where 65000 is the number of times to iterate the statement $hash =
> > md5($hash . $salt . $password) to compute the hash (starting with
> > $hash = ""). The value for new passwords would be set through a
> > config variable (e.g. $wgPasswordIterations), with old
> records updated
> > to use the current iteration count on login.
>
> Well, I did consider it, back in 2003, the tradeoff of course
> is speed.
> Because we're working in PHP, an attacker could do the same
> operation several times faster than we could, using C/C++.
> Serving web pages is meant to be fast, with lots of
> concurrent requests, and there might be a need to do batch
> operations. There's probably an argument for stretching it
> out to a few milliseconds, but with 65000 iterations I get
> 130ms on zwinger which is probably going a bit too far.
>
> -- Tim Starling

Hi,
Quite a few projects seem to be standardising on
http://www.openwall.com/phpass/

It has stretching, and the number of iterations are stored within
the hash, so the strength of the hashes can be upgraded over time.

Jared


_______________________________________________
Wikitech-l mailing list
Wikitech-l [at] lists
https://lists.wikimedia.org/mailman/listinfo/wikitech-l


Platonides at gmail

Jun 7, 2008, 3:43 AM

Post #8 of 8 (6443 views)
Permalink
Re: Password hash format [In reply to]

Regarding the specific implementation:
http://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/includes/User.php?r1=35923&r2=35922&pathrev=35923

comparePasswords() will treat future methods as Old-Style. I think it
would be preferable to determine as old-style only if $type[0] != ':'
and let hooks be able to handle unknown cases failing to "don't know
this codification" if noone is able to detect it.


I don't like that comparePasswords and crypt are doing the same thing
(knowing the intrinsecs of the hashing formats).

Same with oldCrypt, which should be a special case of crypt.

Expressed into code, it could be something like this:

static function cryptPassword( $password, $salt = false, $method = null,
$showMethod = true) {
$hash = "";
if ($method === null)
$efectiveMethod = $wgPasswordSalt ? "B" : "A";
else
$efectiveMethod = $method;


switch ($efectiveMethod) {
case "A":
$salt = false;
$hash = md5( $password );
break;
case "B":
if ( $salt === false )
$salt = substr( wfGenerateToken(), 0, 8 );
$hash = md5( $salt.'-'.md5( $password ) );
break;
default: if (wfRunHooks('cryptPassword', array(&$hash, $password,
$salt, $method)))
throw new MWException("I have no idea how to handle password
method $efectiveMethod!");
}

if ($showMethod) {
if ($salt !== false)
$hash = "$salt:$hash";
$hash = ":$efectiveMethod:$hash";
}
return $hash;
}


static function comparePasswords( $hash, $password, $userId = false ) {
$A = explode( ':', $hash, 4 );
if (count(A) < 4)
return cryptPassword($password, $userId, null, false) == $A[0];
else
return cryptPassword($password, $A[2], $A[1]) == $A[3];
}


Opinions?


_______________________________________________
Wikitech-l mailing list
Wikitech-l [at] lists
https://lists.wikimedia.org/mailman/listinfo/wikitech-l

Wikipedia wikitech RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.