0

I seem to have tried every way to get my log in working however when i attempt to log in it stops at the users password and never fetches it.I am using sha1 in my register and that works fine when inserting into the database.

$username = $_POST['username'];
$password = md5($_POST['password']);

$result = mysql_query("SELECT * FROM users WHERE username = '$username' ");



while ($row = mysql_fetch_array($result))
{
    if($username == $row['username'] )
    {
        if( $password == $row['password'])
        {
            header("location: profile.php");
        }
        else    
            echo 'pass problem';
    }
    else

        echo 'username issue ';


}
jamO
  • 11
  • 1

3 Answers3

2

So many issues...

  1. md5 is not secure. Use a salt + key + password.
  2. mysql_ functions are deprecated. Use mysqli_ or PDO
  3. No sanitation. Use prepared statements and bound parameters.
  4. Don't SELECT *. Get only the columns you need.
  5. Add a LIMIT for how many results you want to return
  6. No need for a while loop for a single result.
  7. How is the password being stored in the database? Obviously an md5'd password isn't matching to your column.

The actual problem

You can't mix encryption types if the user's password is stored as sha1 and then compared to md5.

Kermit
  • 33,827
  • 13
  • 85
  • 121
1

I recommend using the PHPass library to secure your passwords, since md5 and shai and other encryption algorithms are NOT safe.

PHPass takes care of

  1. Encrypting.
  2. Salting.
  3. Stretching.

And that method has not yet been cracked (brute forcing can not be considered as an crack for PHPass).

You can get it from here: http://www.openwall.com/phpass/

IT's very easy to hash once you've set up the code:

$hash = PasswordHash($iteration_count_log2, $portable_hashes)

And then you can fetch the stored hash from the database, and match the login-password-hash with the existing hash via the function

$auth = CheckPassword($incomingPasswordNotHashed, $hashFromDatabase);

I like to make it simpler by doing something like this to make an hash:

// Usage:   $hash = PHPhass($password);
// Pre:     $password is of type string,
//          indicating the password which
//          the user want's to hash.
// Post:    $hash is the hashed password.
function PHPhass($password)
{
    $unHashed = $password;
    require '../phpass/PasswordHash.php';
    header('Content-type: text/plain');
    $t_hasher = new PasswordHash(12, FALSE); // Define the iterations once.
    $hash = $t_hasher->HashPassword($unHashed);
    unset($t_hasher);
    return $hash;
}

And doing this to match a hash and a non-hashed password:

// Usage:   $check = PHPhassMatch($password, $hash)
// Pre:     $password is of type string,
//          indicating a user's passwordd
//          $hash is a hashed password.
// Post:    $check is true if $password's hash
//          value is equal to $hash.
function PHPhassMatch($password, $hash)
{
    $unHashed = $password;
    $theHashed = $hash;
    require '../phpass/PasswordHash.php';
    header('Content-type: text/plain');
    $t_hasher = new PasswordHash(8, FALSE);
    $check = $t_hasher->CheckPassword($unHashed, $theHashed);
    unset($t_hasher);
    return $check;
}

Also, like Fresh mentioned:

  • Don't use the mysql_* since It's deprecated, I recommend using PDO or mysqli.
  • Use prepared statements to prevent sql injection.
  • Don't assume that the posted variables are posted, check if they exist with isset()

You mentioned shai1, are you sure that the passwords in the database are not sha1 but you're matching against md5?

Jonast92
  • 4,964
  • 1
  • 18
  • 32
  • 1
    A few notes: 1. It's SHA, not shai. 2. The order of items in the ordered list is incorrect: first salt, then hash. 3. There is a distinction between encryption and hashing, you don't want to encrypt a password, you want to hash it. 4. If brute forcing can't be considered a crack for this class, don't use it! With the currently available clouds and GPUs, brute forcing should be considered a serious threat. I haven't looked at this class, but the amount of stretching that is appropriate completely depends on what you need to hash. For instance, I want hashing a password to take 100msec. – Pelle Apr 16 '13 at 20:53
  • I know the difference between hashing and encryption, but It's good that you pointed it out for others to read. But seriously? @PelletenCate where to begin... You can ALWAYS bruteforce a password if the user created a bad password, no hashing can EVER change that, so don't say that a library is bad if it can't safe you from brute forcing, NOTHING can save you from brute forcing except for a good password. Also, the library is designed so you never stretch it more than 72 times but you can customized it, I think 12 was the standard one. Anyway I think you should read more about the topic. – Jonast92 Apr 16 '13 at 20:57
  • @Jonast92: true. A dictionary password will never be safe. But with sha1+salt even an 8 character random password (a-zA-Z0-9+chars, 94 in total) will fall quickly. However, with BCrypt a 6 character *random* password of the same make will stand for quite a lot longer. Additionally, I'm not sure where you get *72 times* from, but that's not true at all. phpass (the one you link) uses bcrypt. And the cost is a 2^n number. so a cost of 12 indicates 2^12, or 4096 cost. Additionally, the API you show as examples (phphass, etc) are not from phpass. I don't know what they are... – ircmaxell Apr 16 '13 at 21:44
  • I should say I didn't read the specs of this class so it may have been a bit early to judge its options. (I did do quite some research on cryptography though, so I respectfully doubt your judgement about my cryptographic literacy). Seems it's using bcrypt, which as you'll probably know is based on a cipher-based algorithm (rather than a modern hashing algorithm), which is something I would favour for reasons described [here](http://bit.ly/ZYM718). And using two-phase salting (including one server-specific private key) should make even bruting trivial passwords pretty hard. I stand corrected. – Pelle Apr 16 '13 at 21:56
  • Valid points. Also concerning the PasswordMatch function, it was a home-made function which used the CheckPassword function but saved some extra things that I didn't want to bother me. Also the PasswordHash were also homemade, so that the number of iteratins were hidden; I'm sorry for this confusion. Anyway, correct, the maximum password length is 72, the iterations should of course not be so many. – Jonast92 Apr 17 '13 at 14:28
  • I added the home-made functions which use the PHPass functions, just making it more simple and made it a bit more clear. Thanks for the points guys. – Jonast92 Apr 17 '13 at 14:32
0

If you insert new passwords using sha1, you have to use sha1 on password compare, too. If you compare a md5 string to a sha1 string it doesn't work. So you have to do this:

$password = sha1($_POST['password']);
LingLing
  • 42
  • 1
  • 9