Search code examples
phpmysqlcoldfusioncoldfusion-11

PHP crypt() and Coldfusion


We are moving away from PHP & MySQL to a pure CF/MSSQL platform and I would like to take our user accounts with us, from MySQL.

The user accounts were originally created on the PHP/MySQL site, and stored with an 8-character salt and the MD5-encrypted password, like so:

  • user code: ISzYi6zf
  • password: $1$ISzYi6zf$prff0mAKPVBHNKOlRradj1

With the salt and the encrypted password known to me, I want to be able to "rebuild" the 34 character string from user input in CF, to compare to what is stored in the database.

So far, nothing I have tried in CF has allowed me to "rebuild" the result 34-character string so that I can compare them to what's in the database, ie. I am looking to take user input, add the known salt to it, and come up with a 34 character string in order to compare them.

Thanks for any assistance!

UPDATE:

@Leigh, here is the code that PHP uses to authenticate:

<?
    $user_salt = $_POST["user_salt"];
    $password = $_POST["password"];
    $pass_meth = $_POST["pass_meth"];
    if(strlen($user_salt) > 8 && $pass_meth > 0)
    {
        list($salt1, $salt2) = str_split($user_salt, ceil(strlen($user_salt) / 2));
            $salty_password = $salt1.$password.$salt2;
        $pass_to_use =  md5($salty_password);   
    }
    else
    {
        if(strlen($user_salt) > 8)
        {
            $user_salt = "$1$".str_pad(substr($user_salt, 0, 8), 8, '0', STR_PAD_LEFT)."$";
        }
        else
        {   
            $user_salt = "$1$".substr($user_salt, 0, 8)."$";
        }
        $pass_to_use = crypt($password, $user_salt);
    }
    echo $pass_to_use;
?>

The information we have available in the MySQL DB is as follows:

  • user_email: [email protected]
  • user_code: $1$xxxxxxxx$
  • user_password: $1$xxxxxxxx$xxxxxxx

User password takes the form $1$xxxxxxxx$prff0mAKPVBHNKOlRradj1 - 34 characters, including the prepended user code.

Currently, we are authenticating by having CF send the raw user input (email + password), plus the retrieved user_code (which PHP uses to salt the crypt function) to a PHP page to render the password and compare to what's in the DB.

I am basically at a loss to determine how I can accurately render the user's information in CF, using the existing salt.

Thank you!


Solution

  • (Disclaimer: I am not a PHP guy). Ignoring the basic string functions it looks like the key parts of the code involve two functions: md5 and crypt.

    Crypt

    From what I have read, there is no built in equivalent of PHP's crypt(). However, there is a java implementation of that algorithm in the Apache Commons Codec library, which can be used from CF. Download the latest version of Apache Commons Codec **. Then load the jar via this.javaSettings in your Application.cfc file. Once loaded, you can create an instance of the Md5Crypt class and generate the hash.

    ColdFusion:

    Md5Crypt = createObject("java", "org.apache.commons.codec.digest.Md5Crypt");
    salt = "$1$ISzYi6zf$";
    data = charsetDecode("some value to hash here", "utf-8");
    result = Md5Crypt.md5Crypt(data, salt);
    writeDump( Md5Crypt.md5Crypt(data, salt) );
    

    PHP:

    $salt = "$1$"."ISzYi6zf"."$";    
    $data = "some value to hash here";
    $result = crypt($data , $salt);
    echo $result;
    

    Result:

    $1$ISzYi6zf$lqApYqSEt9fzpSDEZxuK00 
    

    ** Apache Commons Codec is bundled with CF. However, the bundled jar contains a scaled down version which is missing the MD5Crypt class.

    MD5

    Replicating the md5 result is simpler. The equivalent function in CF is Hash(). The only difference being CF converts the result to upper case. Use LCase() to match the PHP result:

    ColdFusion:

    salt1 = "ISzYi";
    salt2 = "6zfXX";
    password = "some value to hash here";
    WriteOutput( lcase(hash(salt1 & password & salt2)) );
    

    PHP:

    $salt1 = "ISzYi";
    $salt2 = "6zfXX";
    $password = "some value to hash here";
    echo( md5($salt1.$password.$salt2) );
    

    Result:

    c23d4661e1ef7866a4296658e3335dbc