search for in the  
<crc32echo>
Last updated: Thu, 19 May 2005

crypt

(PHP 3, PHP 4, PHP 5)

crypt -- One-way string encryption (hashing)

Description

string crypt ( string str [, string salt] )

crypt() will return an encrypted string using the standard Unix DES-based encryption algorithm or alternative algorithms that may be available on the system. Arguments are a string to be encrypted and an optional salt string to base the encryption on. See the Unix man page for your crypt function for more information.

If the salt argument is not provided, one will be randomly generated by PHP each time you call this function.

Some operating systems support more than one type of encryption. In fact, sometimes the standard DES-based encryption is replaced by an MD5-based encryption algorithm. The encryption type is triggered by the salt argument. At install time, PHP determines the capabilities of the crypt function and will accept salts for other encryption types. If no salt is provided, PHP will auto-generate a standard two character salt by default, unless the default encryption type on the system is MD5, in which case a random MD5-compatible salt is generated. PHP sets a constant named CRYPT_SALT_LENGTH which tells you whether a regular two character salt applies to your system or the longer twelve character salt is applicable.

If you are using the supplied salt, you should be aware that the salt is generated once. If you are calling this function repeatedly, this may impact both appearance and security.

The standard DES-based encryption crypt() returns the salt as the first two characters of the output. It also only uses the first eight characters of str, so longer strings that start with the same eight characters will generate the same result (when the same salt is used).

On systems where the crypt() function supports multiple encryption types, the following constants are set to 0 or 1 depending on whether the given type is available:

  • CRYPT_STD_DES - Standard DES-based encryption with a two character salt

  • CRYPT_EXT_DES - Extended DES-based encryption with a nine character salt

  • CRYPT_MD5 - MD5 encryption with a twelve character salt starting with $1$

  • CRYPT_BLOWFISH - Blowfish encryption with a sixteen character salt starting with $2$ or $2a$

Note: There is no decrypt function, since crypt() uses a one-way algorithm.

Example 1. crypt() examples

<?php
$password
= crypt('mypassword'); // let the salt be automatically generated

/* You should pass the entire results of crypt() as the salt for comparing a
   password, to avoid problems when different hashing algorithms are used. (As
   it says above, standard DES-based password hashing uses a 2-character salt,
   but MD5-based hashing uses 12.) */
if (crypt($user_input, $password) == $password) {
   echo
"Password verified!";
}
?>

Example 2. Using crypt() with htpasswd

<?php
// Set the password
$password = 'mypassword';

// Get the hash, letting the salt be automatically generated
$hash = crypt($password);
?>

Example 3. Using crypt() with different encryption types

<?php
if (CRYPT_STD_DES == 1) {
   echo
'Standard DES: ' . crypt('rasmuslerdorf', 'rl') . "\n";
}

if (
CRYPT_EXT_DES == 1) {
   echo
'Extended DES: ' . crypt('rasmuslerdorf', '_J9..rasm') . "\n";
}

if (
CRYPT_MD5 == 1) {
   echo
'MD5:          ' . crypt('rasmuslerdorf', '$1$rasmusle$') . "\n";
}

if (
CRYPT_BLOWFISH == 1) {
   echo
'Blowfish:    ' . crypt('rasmuslerdorf', '$2a$07$rasmuslerd...........$') . "\n";
}
?>

The above example will output something similar to:

Standard DES: rl.3StKT.4T8M
Extended DES: _J9..rasmBYk8r9AiWNc
MD5:          $1$rasmusle$rISCgZzpwk3UhDidwXvin0
Blowfish:     $2a$07$rasmuslerd............nIdrcHdxcUxWomQX9j6kvERCFjTg7Ra

See also md5() and the Mcrypt extension.



User Contributed Notes
crypt
Vlad Alexa Mancini mancin at nextcode dot org
15-May-2005 03:57
cleaner version of shadow() and with more ascii chars

<?php

function shadow ($input){
         for (
$n = 0; $n < 9; $n++){
            
$s .= chr(rand(64,126));
         }
        
$seed "$1$".$s."$";
        
$return = crypt($input,$seed);
   return
$return;
}

>
kevin at sylandroXgetridofthisbitX dot com
20-Apr-2005 02:55
Even worse, using the first two letters of the password as the salt removes the whole point of having salt in the first place, which is that without it, it's trivial to create a dictionary of passwords-to-encrypted-passwords.  Without salt (or with using a salt directly derived from the password) there's only one possible encrypted password per password.  With the two character salt, there's 4096, which makes the idea a lot less feasible.
19-Apr-2005 03:57
>icecube at fr dot fm 07-Mar-2002 09:53
>To generate a .htaccess-based authentication with DES,
>you have to use the first two characters of your password
>as salt.

This is a _really_ bad idea, seeing how the two first letters of your password will be reveiled, effectively reducing the quality of your password.

Your example assigns "sonH/h2hpGtHk" to $ht_pass, where "so" of course are the first to letters in something. Try it out for yourself. Switching the password to "icecube" gives "ickJ.ZxzjXpNE" as the output. Get my point?

The salt is always included in the encrypted string. Use a random salt instead.
postal2600 at yahoo dot com
16-Mar-2005 04:07
I'll take the example from above and take a situation that I've ecountered and show you something that puts this function in a dark shadow of insecurity:

<?php
$password
= crypt('postal2600','CyberBoard');

if (
crypt('postal26??', $password) == $password) {
   echo
"Password verified!";
}
?>

Instad of ?? you can put anything an see that allway the password will be verified. So i strongly recomand that the md5 function should be used instead.
kb at -NOSPAM-diggersdive dot info
30-Dec-2004 10:18
It is likely that the php version of crypt() interfaces relatively directly with the C-library crypt() function, usually contained in libcrypt. 

Depending on your implementation and the default salt, you may or may not get the same crypt'd password out of eight characters as you would a longer string starting with those same eight characters.

See crypt(3) on your system for more documentation on how it works based on different encryption types.
genius at clan-aftershock dot com
28-Nov-2004 07:10
I discovered in the script stated before, when using a salt string the passwords length cannot be longer than 8 characters. However, when not using a salt string, it can exceded that limit.

Modified Example from athony, not using the salt.

<?php
$password
= "qwertyuiopasdfghjkl";

// Not using any salts

$encrypted = crypt($password);

// Now do the comparison

$shortPass = substr($password, 0, 8);

if (
crypt( $shortPass$encrypted ) == $encrypted )
   echo
"The passwords match";
else
   echo
"The passwords do not match";
?>

This will print: "The passwords do not match"

The check for password would still work if it was correct. Just by shortening the password string to eight, or extending the substr, or decalring the shortpass the same as the pass, it would be: "The passwords do match"

So the eight letter limit only works when using a salt.
antony at anonymous dot anon dot com
26-Nov-2004 10:21
There appears to be a limitation with this function, where it only validates upto a characters, therefore the 9th character onwards can be ommitted, which limits useful passwords to 8 characters only. Example

<?php
$password
= "qwertyuiopasdfghjkl";

// Encrypt the password, but let's use a known MD5 hash as the salt

$salt = ""0f2d92cee71e5f93f3abecdc666a6b7d";
$salt = substr($salt, 0, CRYPT_SALT_LENGTH );

$encrypted = crypt($password, $salt);

// Now do the comparison

$shortPass = substr($password, 0, 8);

if (crypt(
$shortPass$encrypted ) == $encrypted )
   echo "
The passwords match";
else
   echo "
The passwords do not match";
?>

This will print: "
The passwords match" even though $shortPass is "qwertyui" and $password is "qwertyuiopasdfghjkl"
thorhajo at gmail dot com
02-Sep-2004 05:34
Here's a little function I wrote to generate MD5 password hashes in the format they're found in /etc/shadow:

function shadow($password)
{
  $hash = '';
  for($i=0;$i<8;$i++)
  {
   $j = mt_rand(0,53);
   if($j<26)$hash .= chr(rand(65,90));
   else if($j<52)$hash .= chr(rand(97,122));
   else if($j<53)$hash .= '.';
   else $hash .= '/';
  }
  return crypt($password,'$1$'.$hash.'$');
}

I've written this so that each character in the a-zA-Z./ set has a 1/54 of a chance of being selected (26 + 26 + 2 = 54), thus being statistically even.
aidan at php dot net
05-Jul-2004 09:52
Text_Password allows one to create pronounceable and unpronounceable passwords.

http://pear.php.net/package/text_password
php at SPAM_tlarson dot com
26-Jun-2002 12:17
There's always been a bit of confusion as to what makes a good salt and what doesn't.  Remember that it doesn't matter at all how easy a salt is to guess. No one ever HAS to guess the salt: it's already given.

The only only important consideration when generating a salt is to make sure that all salts are unique--that way the same password will be encrypted differently (i.e. the encrypted passwords will look different) for different users.

One of the simplest ways to generate a unique salt is to use some string that will be different every time the procedure is called.  Here's a simple example:

<?php
$jumble
= md5(time() . getmypid());
$salt = substr($jumble,0,$salt_length);
?>

Given a string consisting of the current time (in seconds) concatinated with the current process id, the string will never be the same twice, assuming that the function is never called more than once per second.  Calculating the md5 sum over that string creates another string from which you can extract any substring and still end up with a unique sequence.

If you're going to be generating more than one password per second, just throw a rand($x,$y) in there to add a little more entropy.

<crc32echo>
 Last updated: Thu, 19 May 2005
Copyright © 2001-2005 The PHP Group
All rights reserved.
This unofficial mirror is operated at: The Server Pages
Last updated: Thu May 19 17:35:34 2005 CDT