Better Password Generation (DEVELOP)
Motivation
The code used to generate 'new system generated passwords' in Dakar as of 3889 is very simplistic:
# global used by test harness to give predictable results
use vars qw( $password );
# STATIC function that returns a random password
sub randomPassword {
return $password || int( rand(9999) );
}
I have observer that in practice this give a large number of new passwords of the form
XYYZ, that is the middle two digits being the same. I don't know why this is.
The second motivating factor is the limits of the password storage and generation system, its implicit and exlicit assumptions.
Implicit and Explicit Constraints
- There is the assumption that once the user has been given the new four-digit password he/she will log in and change it to soemthng more memorable and more complex.
I do not think this assumption is valid
- Unlike UNIX and MS-Windows systems there is no mechanism that forces a "change password after first use following administrative reset". The use could continue to use the weak 4-digit password indefinitely.
The code that generates the unique URL for the edit function is a good bit better.
Suggestions
- I do not see a way to enforce a "change password after first use following administrative reset" without a great deal of session tracking.
- We do not have the necessary infrastrucure to deal with encrypted, signed E-mail from arbitrary internet based users.
- We must ensure that all user topics and all newly generated user topics have the
ALLOWTOPICCHANGE set to ensure the topic can only be edited by the owner.
Code Suggestion 1
This is just a longer version of the curent implementation. It is still numeric. It is a minimal change.
# STATIC function that returns a random password
sub randomPassword {
return $password || sprintf("%x%lx", rand(0xffff), rand(0xffffffff) ) ;
}
Code Suggestion 2
This is a much larger change and can be used to produce passwords of minimum length and arbitrary mix of charectars.
It has two "advantages':
- The password is _un-_memorable enough that there is a high incentive to change it
- If it isn't changed then it is fairly 'strong'
# STATIC function that returns a random password
sub randomPassword {
my @alphabet = (
'0' .. '9', ';', '+', '=',
'!', '@', '#', '$', '%', '^', '&', '*',
'(', ')', '<', '>', ',', '.', '?', '/',
'a' .. 'z',
'A' .. 'Z',
'Af', 'pfish', 'CzC', 'Oz0', ':-)', '^oOo^', '@=@' # supports poly-glyphs as well
) ;
my $passwd = '';
for (1 ..8) {
$passwd .= $alphabet[rand(@alphabet)];
}
return $passwd ;
}
Epliogue
This isn't really a solution. Passwords are not really a secure solution, they are just something that is easy to implement and widely recognised by the user community. The trend at the corporate level is towards alernate methods such as biometrics and two-factor. Even microsft has
announced
it is heading that way.
See Also
which I very strongly recommend.
http://www.amazon.com/exec/obidos/tg/detail/-/0201615991/qid=1076093927//ref=pd_ka_1/104-7164757-9909538?v=glance&s=books&n=507846
(I've had two copies stolen so far.)
--
AntonAylward - 26 Mar 2005
Comments
I've tried, in turn, removing the "default static" value from the expression and adding a call to -srand()= for each
TWiki::User::new() and altering the call to
rand() as per suggestions in te Camel-3 book.
When I do a bulk reset
most of the passwords are the same.
I still can't see why this is.
True enough, the various calls to
rand() occur during the lifetime of one
CGI invocation.
Its as if the expression is actually
return ($password = ($password || int rand(9999))) ;
that is the value from the first call to
rand() is being retained.
So I changed it to simply
return int rand(9999) ;
but to no avail.
There's something goin on here that I'm not seeing. Can anyone help me out?
--
AntonAylward - 29 Mar 2005
The Fix Is In
OK, I found it.
The Camel-3 book discussed
srand() on page 800. It says:
Do not call srand multiple times in your program .... The point of the rnad function is to 'seed' the rand function so it can produce a different sequence each time you run your program. Just do it once at the top of your program or you won't get random numbers out of rand.
The
srand() is called in
htpasswdGeneratePasswd() to generate the
salt when making a new password. The random integer is handed to this function.
Having
srand called there was resetting the seed to the same value every time! Well OK, it uses
time().... but this was a very, very fast machine. If I'd been debugging on a slow machine I might not have seen this bug!
But that's not the place for it anyway.
It's now in DEVELOP 3938
--
AntonAylward - 30 Mar 2005