note 53848 added to function.crypt
| From: | MagicalTux at FF dot st | Date: | Wed, 15 Jun 2005 07:53:27 +0000 |
| Subject: | note 53848 added to function.crypt | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-90446@lists.php.net to get a copy of this message | ||
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
----
Manual Page -- http://www.php.net/manual/en/function.crypt.php
Edit -- http://master.php.net/manage/user-notes.php?action=edit+53848
Delete: added to the manual -- http://master.php.net/manage/user-notes.php?action=delete+53848&report=yes&reason=added+to+the+manual
Delete: bad code -- http://master.php.net/manage/user-notes.php?action=delete+53848&report=yes&reason=bad+code
Delete: spam -- http://master.php.net/manage/user-notes.php?action=delete+53848&report=yes&reason=spam
Delete: useless -- http://master.php.net/manage/user-notes.php?action=delete+53848&report=yes&reason=useless
Delete: other reasons -- http://master.php.net/manage/user-notes.php?action=delete+53848&report=yes
Reject -- http://master.php.net/manage/user-notes.php?action=reject+53848&report=yes
Search -- http://master.php.net/manage/user-notes.php