Re: crypt() problems..help!
| From: | Dean Hall | Date: | Mon, 25 Sep 2000 14:11:45 +0000 |
| Subject: | Re: crypt() problems..help! | ||
| References: | 1 | Groups: | php.general |
| Request: | Send a blank email to php-general+get-17385@lists.php.net to get a copy of this message | ||
> I have encrypted pw's stored in my database for my users.. it turns out
that
> they can leave up to 2 characters off the password, or add seemingly any
> number of characters AFTER their password, and the encrypted values will
> match, and they will be allowed access.
>
> Example: user joe has password qwertyuiop
> joe can enter:
>
> qwertyui
> qwertyuio
> qwertyuioplkjhgjhds
>
> and all will match the encrypted value in the database.
I'm assuming you're using Unix of some sort. It's possible that the crypt()
function on your system is old and only hashes the first 8 characters of any
string. Anything after that is thrown away. I'm not sure what type of
hashing is done here, but the newer versions, I believe, use a modified DES
algorithm to hash a variable-length string to a fixed length hash value;
some systems use MD5. I'm not sure what you would need to do to upgrade your
version of crypt() -- perhaps upgrading your development libraries or your
kernel?
You might even try adding a 12-character salt (starting with $1$) as the
second argument to php's crypt() function to force it to use MD5 (if it's
available) -- or a 16-character salt (starting with $2$) to make it use
Blowfish. I'm not sure if PHP returns a string with the salt embedded in it,
but you'd need to "remember" the salt so you could use it again when you're
comparing a user-entered password to the stored value.
Well, you could even switch to the md5() function. This function is
guaranteed to produce a fixed-length hash from variable-length text -- this
would solve your 8-character problem. The MD5 algorithm, however, is known
to have a weakness or two, so if you need absolutely unexploitable hashed
passwords, don't use it. For most people, though, md5 should be fine.
If you really want to use crypt(), look in the man pages for crypt() on your
system to see what encryption options you have available.
Dean.
>
> The process I use to generate passwords is:
>
> $PASSWORD = genpassword(10);
> $CRYPTPW = crypt($PASSWORD, mysalthere);
>
> --
>
>
> function genpassword($length){
>
> srand((double)microtime()*1000000);
>
> $vowels = array("a", "e", "i", "o", "u");
> $cons = array("b", "c", "d", "g", "h",
> "j", "k", "l", "m", "n", "p",
> "r", "s", "t", "u", "v", "w",
> "tr",
> "cr", "br", "fr", "th", "dr",
> "ch", "ph", "wr", "st", "sp", "sw",
"pr",
> "sl", "cl");
>
> $num_vowels = count($vowels);
> $num_cons = count($cons);
>
> for($i = 0; $i < $length; $i++){
> $password .= $cons[rand(0, $num_cons - 1)] . $vowels[rand(0,
> $num_vowels - 1)];
> }
>
> return substr($password, 0, $length);
> }
>
> --
>
> and the code used to authenticate users..
>
> $query = mysql_query("SELECT USERID from admin where
USERNAME='$USERNAME'");
>
> $PASSWORD = crypt($PASSWORD, mysalthere);
> if ($row = mysql_fetch_array($query)) {
> $USERID = $row["USERID"];
> }
>
> if (@$USERID && @$PASSWORD) {
> $res = mysql_query("SELECT USERID FROM admin where
> USERID='$USERID' AND PASSWORD='$PASSWORD'");
> if ($row = mysql_fetch_array($res)) {
> $verified_admin = $row["USERID"];
> }
>
>
> I checked the mysql db field.. it's a varchar of 20, which appears to be
> long enough to store the value.
> The password field in the form has no minimum length.
>
> I echoed the output of $PASSWORD in the authenticate screen to make sure
> that all of the encrypted values for those different passwords were coming
> back .. they were, and they were all the same. I am totally stumped. Can
> anyone help?
>
> Chad Day
> Beach Associates