note 21571 deleted from function.md5 by jimw
| From: | jimw@php.net | Date: | Sat, 08 Feb 2003 19:48:27 +0000 |
| Subject: | note 21571 deleted from function.md5 by jimw | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-43633@lists.php.net to get a copy of this message | ||
Reply to dgolesny@avo-web.de's comment on 15-Feb-2002:
To be very security conscious, using your script as written isn't a good idea either. You have
the following:
function generatekey($count) {
mt_srand((double)microtime()*1000000);
$key = "";
for ($i=0; $i<$count; $i++) {
$c = mt_rand(0,2);
if ($c==0) {
$key .= chr(mt_rand(65,90));
} elseif ($c==1) {
$key .= chr(mt_rand(97,122));
} else {
$key .= mt_rand(0,9);
}
}
return $key;
}
The problem is with how you use $c. $c is either 0, 1, or 2, which is how you decide which class of
character to randomly append to $key. You equally weighted the choices made by $c. Partitioning up
the possible choices like this means that any character going into the password is chosen from less
than half of the possible choices, and sometimes less than 1/6th of the possible choices (when $c =
2).
One third of the time, $c will equal 2. This means a full third of any generated password will
consist of the numerals 0 to 9. In other words, there is a 33% chance any character in a password
is one of ten characters instead of any character being evenly distributed over a possible 62.
Patterns like this make attackers happy because they're easy to exploit and even easier to
search.
Instead of a password of length n being one of 62^n possibilities, it will be one of [26^(n/3)] *
[26^(n/3)] * [10^(n/3)] (if I'm thinking correctly). For a nine character password, the first
scheme gives you 13537086546263552 (1.35 * 10^16) combinations, but yours only gives 308915776000
(3.08 * 10^11) combinations, which is about .001% of the possible keyspace. In other words, if it
took a computer 24 hours to check the whole keyspace of n-character passwords as defined above, the
keyspace generated by your algorithm could be brute-forced in under one second.
To fix this, randomly generate a number between 1 and 62 inclusive and translate that to a character
to append. Even better, include punctuation as well. The more possible characters in a password,
the harder it will be to break and the more possible combinations there are of those characters the
better.