note 53848 deleted from function.crypt by joey

From: Date: Mon, 27 Dec 2010 12:19:31 +0000
Subject: note 53848 deleted from function.crypt by joey
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-175225@lists.php.net to get a copy of this message
Note Submitter: MagicalTux at FF dot st ---- Since many of you are wondering why when providing salt the characters over the 8th are ignored in the password, I'll clarify it a bit. By default, PHP will try to use the best encryption method available on your system : MD5 or Simple DES. Usually this is the MD5 method ($1$). In this case, the salt must look like : "$1$xxxxxxxx$" where x are random ASCII characters. When you use MD5 passwords, all characters of the password are encrypted in this 34 characters hash. However if your salt starts with an ASCII character, the system will assume it's a standard DES encrypted password. The main weakness of this system : only the 8 first characters of the password are used. A correct version of the code : <?php function makesalt($type=CRYPT_SALT_LENGTH) { switch($type) { case 8: $saltlen=9; $saltprefix='$1$'; $saltsuffix='$'; break; case 2: default: // by default, fall back on Standard DES (should work everywhere) $saltlen=2; $saltprefix=''; $saltsuffix=''; break; # } $salt=''; while(strlen($salt)<$saltlen) $salt.=chr(rand(64,126)); return $saltprefix.$salt.$saltsuffix; } $salt=makesalt(); $longpassword='fez1c89ez1c98ez4c89z4eqf98ez'; $encrypted = crypt($longpassword, $salt); $encrypted2 = crypt(substr($longpassword, 0, 8), $encrypted); if ($encrypted == $encrypted2) { echo 'Match: Weak encryption method (Standard DES)'; } else { echo 'NoMatch: Strong encryption method (MD5)'; } ?> If you use makesalt(2) you will force usage of Standard DES method, and the passwords will match. If you just use makesalt() there's great chances you'll have a MD5 password (don't know any system used nowadays which does not support MD5 passwords). Finally, do not look at md5() PHP function if you want a md5 password, that's not related. UNIX MD5 passwords uses a salt, are 34 character long and start with $1$. The reply from md5() is 32 characters long, and is more adapted for file integrity check (call that a checksum). Some people use sha1() passwords but without salt. Here's my simple sha1crypt function which will work with standard crypt passwords (by calling crypt()) AND a home-made "sha1" encryption method. <?php // NOTE: This function requires PHP 5.0.0 as we use "raw output" option of sha1() function sha1crypt($password, $salt=null) { if ( (is_null($salt)) || (strlen($salt)<1) ) { $salt=''; while(strlen($salt)<10) $salt.=chr(rand(64,126)); $salt='$sha1$'.$salt.'$'; } if ($salt{0}!='$') return crypt($password, $salt); $tmp=explode('$',$salt); if ($tmp[1]!='sha1') return crypt($password, $salt); $saltstr=$tmp[2]; if (strlen($saltstr) != 10) return crypt($password, $salt); $encrypt=base64_encode(sha1($saltstr.$password,true)); return '$sha1$'.$saltstr.'$'.$encrypt; } // without salt, sha1crypt() will generate on $pass=sha1crypt('foobar'); echo $pass."\n"; // pass directly password as salt - different output as password is not the same echo sha1crypt('foobarbaz',$pass)."\n"; // same password - same output echo sha1crypt('foobar',$pass)."\n"; // Encrypt using MD5 passwords echo sha1crypt('foobar','$1$blahblahg$')."\n"; ?> will output: $sha1$oFkYeI|vuu$d3n7D30OnecZSbS6KIbxCch608A= $sha1$oFkYeI|vuu$iA8KmbCZun1G1gEw2qVr42ELVH4= $sha1$oFkYeI|vuu$d3n7D30OnecZSbS6KIbxCch608A= $1$blahblah$/8Hme91aEkHzLaVk0g9EQ0 My sha1-encrypted passwords are 45 characters long. Remember to read that too before using SHA1 passwords too : http://www.schneier.com/blog/archives/2005/02/sha1_broken.html

« previous php.notes (#175225) next »