Solved

PHP 5.3.3. Crypt function

Posted on 2013-12-25
10
1,277 Views
Last Modified: 2013-12-26
I am trying to create an authentication mechanism using the crypt funtion.
In the php.net it says the following example:

<?php
$hashed_password = crypt('mypassword'); // let the salt be automatically generated
if (crypt($user_input, $hashed_password) == $hashed_password) {
   echo "Password verified!";
}
?>

My assumption that you will generate the hashed password in the first command, and later you retrieve it from a db and use the second command to verify it, but that doesn't work, but furthermore even the script as above did not work with me as every time the crypt is running it generates a different hash because it is using a randomly generated salt.

So instead I found this script is working with me:

<?php
$hashed_password = crypt('mypassword',$salt); // Use the same salt always
if (crypt($user_input, $salt) == $hashed_password) {
   echo "Password verified!";
}
?>

My question is me understanding is correct? or I am misusing the function which might cause a security hole in my mechanism?
0
Comment
Question by:Ashraf Hassanein
  • 4
  • 3
  • 2
  • +1
10 Comments
 
LVL 82

Assisted Solution

by:Dave Baldwin
Dave Baldwin earned 100 total points
ID: 39739712
You are sort of correct but there is more to it.  See this page: http://www.php.net/manual/en/function.crypt.php  The wrapper function password_hash()  may be more suitable.

MD5 http://www.php.net/manual/en/function.md5.php and SHA http://www.php.net/manual/en/function.sha1.php are still frequently used though this page http://www.php.net/manual/en/faq.passwords.php recommends against them.

It depends as much on how much it is worth it to break into your system or web site.  Brute force cracking MD5 and SHA1 hashes still requires a fair amount of computer power.  If there is real money to be made or military and/or industrial secrets to be had, then the most powerful methods should be used.  Of course, you might not be using PHP in those cases anyway.
0
 
LVL 76

Expert Comment

by:arnold
ID: 39739723
There are several options. One deals with you storing the php hashed password in the database. On login, the hashed password you stored in the database is the salt for validation of the user provided password during subsequent logins.
You seem in your initial part rehashing presumably the stored hashed password which is the reason it did not work.
The other option is to rely on the encryption mechanisms that exist in the database server.


The second option means the password is stored in plain text within the database.

To illustrate the first option. During account creation/password changes
You would hash the password and then write the result into the database.
When a user attempts to login, you would retrieve the hashed password from the database and then within php and your comparison will be to compare $database_hashed_password == crypt($userprovidedpassword,$database_hashed_password)

If you use mysql you can validate via a single select
I.e. If a record is returned the info provided was correct. ( you use the mysql_real_escape_string() for both username and password from the page method to encode user input to avoid sql injection
select * from list_users where username=$username and password=PASSWORD($user_provided_password,password)


http://dev.mysql.com/doc/refman/5.5/en/encryption-functions.html
0
 

Author Comment

by:Ashraf Hassanein
ID: 39739736
Hi Dave thanks, I was planning to use the password_hash but it is not available in my php5.3.3 also I tried to upgrade to 5.5 to use this feature but 5.5 is not available on the standard centos repository yet and I'm not so much in favor for this upgrade yet not to mess with the othe php plugins , so I used crypt.
Hi Arnold, thanks for the explanation but I am really trying to store the password in hash format and then retrieve and compare it with the user input, but my problem that crypt ($ user_input,$ hashed_pass) will never give a value of $ hashed_pass where in my case the  $ user_input is the flat inpu to of the user comming from the login form and $ hashed_pass is the initial hashed password stored in the db, and I don't know why, however the only thing I noticed that crypt ("my_password") is always giving different value unless you use with it the salt, what do you think? , by the way I am using pgdb.
0
 
LVL 108

Accepted Solution

by:
Ray Paseur earned 400 total points
ID: 39739930
Here is my teaching example showing how to encrypt and decrypt information, as well as how to encode it for safe transport over binary-sensitive interfaces, such as the internet or the SQL server.  You might also be interested in this article about PHP client authentication.

Please see http://www.laprbass.com/RAY_encrypt_decrypt.php

<?php // RAY_encrypt_decrypt.php
error_reporting(E_ALL);

// MAN PAGE: http://php.net/manual/en/ref.mcrypt.php

class Encryption
{
    protected $key;

    public function __construct($key='quay')
    {
        // THE KEY MUST BE KNOWN TO BOTH PARTS OF THE ALGORITHM
        $this->key = $key;
    }

    public function encrypt($text)
    {
        // ENCRYPT THE DATA
        $data = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $this->key, $text, MCRYPT_MODE_ECB);

        // MAKE IT base64() STRING SAFE FOR STORAGE AND TRANSMISSION
        return base64_encode($data);
    }

    public function decrypt($text)
    {
        // DECODE THE DATA INTO THE BINARY ENCRYPTED STRING
        $text = base64_decode($text);

        // DECRYPT THE STRING
        $data = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $this->key, $text, MCRYPT_MODE_ECB);

        // DECLOP NUL-BYTES BEFORE THE RETURN
        return trim($data);
    }
}

// INSTANTIATE AN ENCRYPTION OBJECT FROM THE CLASS
$c = new Encryption();

// INITIALIZE VARS FOR LATER USE IN THE HTML FORM
$encoded = '';
$decoded = '';

// IF ANYTHING WAS POSTED SHOW THE DATA
if (!empty($_POST["clearstring"]))
{
    $encoded = $c->encrypt($_POST["clearstring"]);
    echo "<br/>{$_POST["clearstring"]} YIELDS ENCODED ";
    var_dump($encoded);
}

if (!empty($_POST["cryptstring"]))
{
    $decoded = $c->decrypt($_POST["cryptstring"]);
    echo "<br/>{$_POST["cryptstring"]} YIELDS DECODED ";
    var_dump($decoded);
}

// CREATE THE FORM USING HEREDOC NOTATION
$form = <<<FORM
<form method="post">
<input name="clearstring" value="$decoded" />
<input type="submit" value="ENCRYPT" />
<br/>
<input name="cryptstring" value="$encoded" />
<input type="submit" value="DECRYPT" />
</form>
FORM;

echo $form;

Open in new window

HTH, ~Ray
0
 

Author Comment

by:Ashraf Hassanein
ID: 39740004
Thanks Ray, you are always providing great support, but I can see from script that this is a 2 way encryption, and not like hashing which can not be decoded, don't you think that this is a little bit unsecured? what do you advise?
0
Easy Project Management (No User Manual Required)

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39740015
Security is a relative term.  If you want my take on it, you can find a discussion at the end of this article.  Search the text for "An Afterword: About Storing Passwords"
http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/A_2391-PHP-login-logout-and-easy-access-control.html

As we have now learned from the RSA disclosures, encryption of the sort used to protect internet messages was deliberately crippled by RSA in exchange for payments from the US Government.  I don't think you can ever reach a state that implies "completely secure."  Best practices are promulgated through OWASP.  This is good: https://www.owasp.org/index.php/Top_10_2013-Top_10
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39740026
In the category of "security by obscurity" this looks interesting.
http://www.php.net/manual/en/function.base64-encode.php#85831

Perhaps a red-herring could be added to any encrypted data string, much like a "salt" can be added to the md5() string.
0
 

Author Comment

by:Ashraf Hassanein
ID: 39740177
Thanks for your support that was extremely helpful issue solved as usual :-)
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39740201
Thanks for using EE! ~Ray
0
 
LVL 76

Expert Comment

by:arnold
ID: 39740252
Your PHP code was rehashing a password.
crypt 's salt can be new or the hashed password, the only issue crypt may have a different order of (salt, password) or (password,salt)
the two first characters in the response will tell you whether, as I have before, placed the items in the wrong order.

you only posted the code for php handling, so I have no idea what was going wrong.

what characters are you allowing in the password?  the mysql_real_escape.. would encode different characters

in future debug, out put the data to screen this way you can see what is going on with php processing.
i.e. an example of a person's password was sfdde3$d% after the real_escape it turned up as "sfdde3\$\%"
if you then rehash it, it may deviate from the entered password hash.
0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Nothing in an HTTP request can be trusted, including HTTP headers and form data.  A form token is a tool that can be used to guard against request forgeries (CSRF).  This article shows an improved approach to form tokens, making it more difficult to…
By this time the large percentage of day-to-day transactions have shifted to mobile banking; here are some overriding areas QAs must investigate while testing mobile banking apps.  
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now