Reputation: 27
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
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