Jesper Petersen
Jesper Petersen

Reputation: 27

Why is my hash / salt technique for storing passwords not working?

I am trying to make a safe, custom, user login system, but it currently does not work. The idea is to create a user with a safe, encrypted password. However, when using the correct password, it does not log on to the site.

Output when using the password 123456789jp:

$6$j7Rd68RhKNx.6ccH$9lvRDdks.jx4hk7.YQ0hpvzPE22h/BZQ/9yXiwTMBV1Kx2xr2gbIZZJxYjeLrA41nL2WGjmt.FMQi877uOXrP1

Relevant function:

// function register_user()
function bruger_opret_siden(){
            if ($stmt = $this->mysqli->prepare('SELECT NULL FROM `bruger` WHERE `brugernavn` = ?'))
            {
                $stmt->bind_param('s', $brugernavn);
                $brugernavn = $_POST["brugernavn"];
                $stmt->execute();
                $stmt->store_result();
                $count = $stmt->num_rows;
                $stmt->close();
                if($count > 0)
                {
                    $user_found = 1;
                }
            }
            if(!isset($user_found))
            {
                //Check if the user exists.

                if(!isset($errors))
                {
                    $pb = null;

                    include 'function/class.upload.php';
                    $handle = new Upload($_FILES["file"]);

                    if($handle->uploaded)
                    {
                        //trims to next request         
                    }

                 $password = $_POST["pass"];
                 $algorithm = '$6$'; //<--- This means the SHA 512
                 $salt = $this->generateSalt(16); //<--- SHA 512 uses a 16-character salt

                 $hash = crypt($password, $algorithm . $salt);

                if ($stmt = $this->mysqli->prepare('INSERT INTO `bruger` 
                (`rank`, `email`, `brugernavn`, `password`, `profilbillede`, `profilbillede_godkendt`, `navn`, `efternavn`, `alder_d`, `alder_m`, `alder_aar`, `status`, `kon`, `seksualitet`, `land_by`, `hojde`) 
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'))
                {

                    $stmt->bind_param('issssisssssiiisi', $rank, $email, $brugernavn, $password, $profilbillede, $pb_godkendt, $navn, $efternavn, $alder_d, $alder_m, $alder_aar, $kon, $seksualitet, $partnerstatus, $land_by, $hojde);
                    $rank = '1';
                    $pb_godkendt = '1';
                    $email = $_POST["email"];
                    $brugernavn = $_POST["brugernavn"];//C
                    $password = $hash;//C
                    $profilbillede = $pb;//C
                    $navn = $_POST["navn"];
                    $efternavn = $_POST["efternavn"];
                    $alder_d = $_POST["alder_d"];
                    $alder_m = $_POST["alder_m"];
                    $alder_aar = $_POST["alder_aar"];
                    $kon = $_POST["kon"];
                    $seksualitet = $_POST["seksualitet"];
                    $partnerstatus = $_POST["partnerstatus"];
                    $land_by = $_POST["land_by"];
                    $hojde = $_POST["hojde"];

                    $stmt->execute();
                    $stmt->close();

                    echo "ok";

                    }
                    else
                    {
                        // There was an error 
                        echo 'error: ' . $mysqli->error;
                    }
                }
            }
            else
            {
                echo "<li id=\"check_not\">Dette brugernavn er optaget!!</li>";
            }
    }

Code to make a hash from the password and a salt to register the user:

function generateSalt($length) {
         $alphabet = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
         $alphabet_length = strlen($alphabet);
         $salt = '';
         for ($i = 0; $i < $length; $i++) {
             $salt .= $alphabet[rand(0, $alphabet_length - 1)];
         }
         return $salt;
     }

Two functions to show users information.

$pass = $mebe->generateSalt();
                $users = $mebe->bruger_opret_siden();

The following function contains the problem; it does not log the user in. While there are no errors produced, it doesn't work.

function godkendt_login()
    {
        if ($stmt = $this->mysqli->prepare("SELECT `id`, `brugernavn`, `rank`, `profilbillede`, `profilbillede_godkendt` FROM `bruger` WHERE `brugernavn` = ? AND `password` = ?"))
        {
            $stmt->bind_param('ss', $brugernavn, $password);
            $brugernavn = $_POST["brugernavn"];
            $password = sha1($_POST["pass"]);
            $stmt->execute();
            $stmt->store_result();
            $stmt->bind_result($id, $brugernavn, $rank, $profilbillede, $profilbillede_godkendt);
            $stmt->fetch();
            $count = $stmt->num_rows;
            $stmt->close();

            if($count > 0)
            {
                $_SESSION["logged_in"] = true;
                $_SESSION["id"] = $id;
                $_SESSION["profilbillede"] = $profilbillede;
                $_SESSION["brugernavn"] = $brugernavn;
                $_SESSION["rank"] = $rank;
                $_SESSION["profilbillede_godkendt"] = $profilbillede_godkendt;

                if($_SESSION["logged_in"] == true)
                {
                    echo "ok";
                }
                else
                {
                    // Sorry, please try again.
                                    echo "Desværre prøve igen."
                }
            }
            else
            {
                          echo "Skrive et password eller brugernavn"
            }
        }
    }

Log file / inc file:

<?php
    /*
     * // Grant the administrative privilige to show the content.
     * Giver admin adgang til se indhold på siden.
     */
    if(isset($_SESSION["rank"]) && $_SESSION["rank"] > 0) {
        $bruger = $mebe->brugerindhold_side();
    }


    /*
     * // Grant normal access to the page.
     * Hvis ingen af dem så få de bare adgang sådan her..
     */
    else{
    ?>
<form name="login" method="post" action="#">
    <h1>Log ind</h1>
    <p>Brugernavn</p><input type="text" name="brugernavn"/>
    <p>Password</p><input type="password" name="pass"/>
    <br />
    <input type="submit" name="Log_ind" value="Log ind" id="login">
    <?php
    if(isset($_POST["Log_ind"]))
    {
    $login = $mebe->godkendt_login();
    }
    ?>
</form>
<?php
    }
?>

Upvotes: 1

Views: 260

Answers (1)

Digitalis
Digitalis

Reputation: 570

Okay, given that I cannot fully grasp your code due to a language difference. A salt should be a reproducible value. From what I gather yours seems to be generated @ random.

If so, the hashes won't add up, therefore the check fails. Use a constant value for the hash and do not store it in a database!

For example:

<?php

     function generateHash($in)
     {
         $salt = "Th1s1sAS4lt";
         return md5(sha1($in) . $salt);
     }
?>

Also, any post value should be checked because it is inputted by a user and may contain illegal characters or harmful code. Observe the following:

<?php
    // Note that the input contains SQL.
    // bemærke, at de input indeholder SQL.                 
    $_POST['passwd'] = "'p@ssword' OR 'a' = 'a'";

    if (tilmeld_dig())
    {
        // Log the user in.
        // brugeren er logget på
    }


    function tilmeld_dig()
    {
        $sql = "SELECT brugernavn from tbl_brugere WHERE adgangskode = " . $_POST['passwd'];

            // Execute the database command. 
        $res// = Database kommando udføre
        if ($res)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
?>

In the example above, the user is logged in no matter the password, because there is an SQL command injected that will always be true.

Though this is a crude example, please review this: http://translate.google.com/translate?hl=nl&sl=en&tl=da&prev=_dd&u=http%3A%2F%2Fwww.unixwiz.net%2Ftechtips%2Fsql-injection.html

I tried to support you with some Danish comment because this is important in security systems. You're on the right track but I recommend you to take a look at my suggestion.

Also, this is untested code, but more or less how it works.

Upvotes: 2

Related Questions