|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #51282 crypt() result different between PHP 5.3.1 and PHP 5.3.2
Submitted: 2010-03-12 10:54 UTC Modified: 2010-03-31 01:48 UTC
Avg. Score:4.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: jerome dot auge at anakeen dot com Assigned: joey (profile)
Status: Not a bug Package: *Encryption and hash functions
PHP Version: 5.3.2 OS: Mac, Linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If this is not your bug, you can add a comment by following this link.
If this is your bug, but you forgot your password, you can retrieve your password here.
Bug Type:
From: jerome dot auge at anakeen dot com
New email:
PHP Version: OS:


 [2010-03-12 10:54 UTC] jerome dot auge at anakeen dot com
I use crypt() to store and validate passwords using the « Standard DES » hash, and after upgrading to 5.3.2, the hashed password of an account is not the same as the one generated with PHP 5.3.1 :

With PHP 5.3.1 :

  $ php -r 'print crypt("anakeen", "A^")."\n";'

After upgrading to PHP 5.3.2 :

  $ php -r 'print crypt("anakeen", "A^")."\n";'

I tested both on Mac (macports) and on Linux (rawhide), and the hash result was different on both platform.

On Mac OS X (10.5), the Perl (or C) crypt gives me the same results as PHP 5.3.1 :

  $ perl -e 'print crypt("anakeen", "A^")."\n";'

While on Linux, the Perl script gives me the same result as PHP 5.3.2.

It appears that there is a difference in the crypt() function, between these platforms, regarding the presence of non alpha-num chars in the salt :

Mac OS X with "A-" salt = different hashes :
  $ php -r 'print crypt("anakeen", "A-")."\n";'
  $ perl -e 'print crypt("anakeen", "A-")."\n"';

Mac OS X with "A9" salt = same hashes :

  $ perl -e 'print crypt("anakeen", "A9")."\n"';
  $ php -r 'print crypt("anakeen", "A9")."\n";'

Maybe I should not have used non alpha-num chars for my salt in the first place ?


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2010-03-12 12:34 UTC]
-Status: Open +Status: Assigned -Type: Bug +Type: Documentation Problem -Assigned To: +Assigned To: joey
 [2010-03-30 00:53 UTC] paul dot fernandez at gmail dot com
I have a similar problem going from PHP 5.2.8 to 5.3.0.

        if(CRYPT_STD_DES == 1) { echo "Standard DES is available.\n\n"; }

        $username = 'aardvark';
        $password = 'password';

        $salt = substr($username, 0, 1);
        echo "\$salt = $salt\n";

        $pass = crypt($password, $salt);
        echo "Standard crypt encryption (1 char salt)  = '$pass'\n";

        $des_pass = crypt($password, 'a$');
        echo "DES encryption (2 char salt) = '$des_pass'\n";

Output from PHP 5.3.0:

$ php test24.php
Standard DES is available.

$salt = a
Standard crypt encryption (1 char salt)  = 'a$Av8awQ0AsR6'
DES encryption (2 char salt) = 'a$Av8awQ0AsR6'

Output of the same code on PHP 5.2.8:

$ php test24.php
Standard DES is available.

$salt = a
Standard crypt encryption (1 char salt)  = 'a$LHSkrbhfU1.'
DES encryption (2 char salt) = 'a$LHSkrbhfU1.'
 [2010-03-30 01:53 UTC]
-Status: Assigned +Status: Bogus
 [2010-03-30 01:53 UTC]
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at and the instructions on how to report
a bug at

The salt has to come from the alphabet "./0-9A-Za-z", and using characters outside this range will result in undefined behaviour. As of 5.3.1, this is handled by not using the illegal characters as part of key in order to have consistent behaviour on all platforms.

 [2010-03-30 23:35 UTC] paul dot fernandez at gmail dot com
You are correct.  When I switched to using a two character alpha-numeric salt, both PHP 5.2.8 and 5.3.0 returned the same encrypted string.  However, if I use a one character alpha-numeric salt, I get a different result on PHP 5.2.8 and 5.3.0:

        $password = 'password';

        $salt = 'a';
        $des_pass = crypt($password, $salt);
        echo "DES encryption (salt = $salt) = $des_pass\n";

PHP 5.2.8:

$ php test27.php 
DES encryption (salt = a) = a$LHSkrbhfU1.

PHP 5.3.0:

$ php test27.php 
DES encryption (salt = a) = a$Av8awQ0AsR6

I wouldn't ordinarily break the rules, so-to-speak, by using a one character salt, but I'm trying to match an encryption created by a one character salt.  Is this also producing undefined behavior because of the shortness of the salt?

 [2010-03-31 00:07 UTC]
Yes, it's definitely undefined behaviour. However, I can't duplicate this - are 
you using 5.3.0 and 5.2.8 on different operating systems? Prior to 5.3.2, PHP 
would call the underlying OS's crypt() - so, on platforms that use the "UFC" 
crypt() (Linux, Sun, certain BSDs) you might get a different result than ones that 
use the FreeSec 1.0 crypt() (Mac OS X, OpenBSD).
 [2010-03-31 01:04 UTC] paul dot fernandez at gmail dot com
Yes, for the output I submitted, I was running this on two different systems, both Solaris 10.  However, for troubleshooting purposes, a coworker installed PHP 5.2.8 on the same system that is running 5.3.0 so that we could test if it was perhaps the OS or some library that was causing this issue, and we still see different encrypted outputs for a single character alpha-numeric salt.

Below is the output of running the same PHP script using two different versions of PHP on the same server:

$ /sw/php/bin/php test27.php 
DES encryption (salt = a) = a$Av8awQ0AsR6

$ /sw/php/bin/php --version
PHP 5.3.0 (cli) (built: Aug 12 2009 19:24:06) 
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2009 Zend Technologies

$ /sw/php528/bin/php test27.php 
DES encryption (salt = a) = a$LHSkrbhfU1.

$ /sw/php528/bin/php --version  
PHP 5.2.8 (cli) (built: Mar 25 2010 19:40:18) 
Copyright (c) 1997-2008 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2008 Zend Technologies

$ uname -a
SunOS *hostname* 5.10 Generic_138888-03 sun4u sparc SUNW,Sun-Fire-V490
 [2010-03-31 01:48 UTC]
That's exactly why we have to fix that in recent 5.3 releases. We also use a common implementation internally to be sure that every OS and no matter which version of PHP (from now on) will get the same results for the same input.
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Sat Dec 07 02:01:25 2019 UTC