've set up two simple php files for a login/register feature on my android app.
I would like to know a simple way to get it to save/write an encrypted password to the mysql database. at the moment its only writing plain text for password.
Code for register.php is :
$username = $_POST["username"];
$email = $_POST["email"];
$password = $_POST["password"];
$statement = mysqli_prepare($con, "INSERT INTO User (username, email, password) VALUES (?, ?, ?)" );
mysqli_stmt_bind_param($statement, "sss", $username, $email, $password);
mysqli_stmt_execute($statement);
mysqli_stmt_close($statement);
mysqli_close($con);
and code for login stuff is:
$password = $_POST["password"];
$username = $_POST["username"];
$statement = mysqli_prepare($con, "SELECT * FROM User WHERE username = ? AND password = ?");
mysqli_stmt_bind_param($statement, "ss", $username, $password);
mysqli_stmt_execute($statement);
mysqli_stmt_store_result($statement);
mysqli_stmt_bind_result($statement, $userID, $username, $email, $password);
$user = array();
while(mysqli_stmt_fetch($statement)) {
$user[username] = $username;
$user[email] = $email;
$user[password] = $password;
}
echo json_encode($user);
mysqli_stmt_close($statement);
mysqli_close($con);
very simple question i know but just learning myself. thanks
EDIT:
Based on Jamesking56's link/ response i've come out with this, but now its not writing to db at all:
$username = $_POST["username"];
$email = $_POST["email"];
$password = $_POST["password"];
$passwordHash = password_hash($password, PASSWORD_DEFAULT);
$statement = mysqli_prepare($con, "INSERT INTO User (username, email, password) VALUES (?, ?, ?)" );
mysqli_stmt_bind_param($statement, "sss", $username, $email, $passwordHash);
mysqli_stmt_execute($statement);
mysqli_stmt_close($statement);
mysqli_close($con);
If you are using PHP 5.5 or newer, there are some built-in functions for password hashing called password_hash() and password_verify().
Never use MD5 or SHA1 on its own for password hashing as they can be reversed by using rainbow tables.
You should use a hashing mechanism with a secret that you define which gives you hashes which are unique to your application. The 'secret' you create should never be shared through VCS.
A good article about this can be found here: http://www.phptherightway.com/#password_hashing
For anyone using PHP versions lower than 5.5 you can use crypt():
http://php.net/manual/en/function.crypt.php
PHP 5.4 will be unsupported as of 14th September 2015 so please consider upgrading to 5.5.
Related
I am working on making a login section for my project website using PHP, but for some reason, verify_password won't return true, even when I am giving the correct password. No idea what I am doing wrong here.
Here is the code that I use to add the user to the MySQL table:
$password= $_POST['password'];
$hash = password_hash('$password', PASSWORD_DEFAULT);
// I know this isn't inject proof
$res = $conn->prepare('INSERT INTO login (SSN, UserName, passhash) VALUES (:SSN, :UserName, :passhash)');
$res->bindValue(':SSN', $_POST['UserName']);
$res->bindValue(':UserName', $_POST['UserName']);
$res->bindValue(':passhash', $hash);
$res->execute();
It stores the hash in a varchar(60)
Here is the code that takes the password, and verifies it against the hash:
$userName = $_POST['UserName'];
$password= $_POST['password'];
// I doubt this is inject proof
$res = $conn->prepare("select passhash from login where UserName='$userName'");
//$res->bindValue(':SSN', $_POST['UserName']);
//$res->bindValue(':UserName', $_POST['UserName']);
//$res->bindValue(':hash', $hash);
$res->execute();
$result = $res->fetch();
if(!empty($result) && password_verify($password, $result['passhash']))
What can I try next?
Single quotes prevent variable interpolation, so this encodes the literal string $password as the password:
$hash = password_hash('$password', PASSWORD_DEFAULT);
Just use the variable directly:
$hash = password_hash($password, PASSWORD_DEFAULT);
The prepare function is not recognizing members that already exist in the DB and as a result, always calls the function NewUser() when it is supposed to go through the else statement? I believe this is because when I ask it to verify the password, it encounters an error, but I have no idea what I am doing wrong?
function NewUser(){
global $dbh;
$fullname = trim($_POST['fullname']); //at a minimus clear whitespace.
$username = trim($_POST['username']);
$email = trim($_POST['email']);
$user_password = trim($_POST['password']);
$options = [
'cost' => 12, //higher = more lower= less. you want it to take around 0.4 seconds for security reasons!
];
$hashed_password = password_hash($user_password, PASSWORD_DEFAULT, $options); // hashed password for storage!
$stmt = $dbh->prepare("INSERT INTO USERS(fullname, username, email, password) VALUES('$fullname', '$username', '$email', '$hashed_password')");
$stmt->bindValue(1,$fullname,PDO::PARAM_STR);
$stmt->bindValue(2,$username,PDO::PARAM_STR);
$stmt->bindValue(3,$email,PDO::PARAM_STR);
$stmt->bindValue(4,$user_password,PDO::PARAM_STR);
if($stmt->execute()){
echo "<div class= container>","<div class = \" col-md-2 connout slideInTop\">"," <span class = \"username_text\">$username</span>, <br> welcome to <br> the <br> <span class = \"vibecourt_text\">VIBECOURT</span> family! <br><br> You may <br> now sign in <br> below","</div>","</div>";
}
}
function SignUp(){
global $dbh;
//checking the 'user' name which is from index.php, is it empty or have some text
if(!empty($_POST['username'])){
$username = trim($_POST['username']);
$password = trim($_POST['password']);
$stmt = $dbh->prepare("SELECT * FROM USERS WHERE (username = ? AND password = ?)");
$stmt->bindValue(1, $_POST['username'],PDO::PARAM_STR);
$stmt->bindValue(2, $_POST['password'],PDO::PARAM_STR);
$stmt->execute();
$selected_row = $stmt->fetch(PDO::FETCH_ASSOC);
//check password agaisnt stored hash
if(!password_verify($password, $selected_row['password'])) {
NewUser();
}
else{
echo("<script>location.href = 'pages/home/home.php'</script>");
}
}
}
SignUp();
Updated Answer
In light of what transpired in comments... it appears the issue is further rooted far above where you are originally storing the hashed password into the database.
You say you are using a varchar(50), for a password_hash value. This is too short, and mysql is no doubt clipping the INSERT. This will result in hashes that can never be matched.
You should have a varchar(60) at the very minimum, but PHP.net states that this hash can grow over time, and using a varchar(255) is recommended.
In this bit:
$stmt = $dbh->prepare("SELECT * FROM USERS WHERE (username = ? AND password = ?)");
$stmt->bindValue(1, $_POST['username'],PDO::PARAM_STR);
$stmt->bindValue(2, $_POST['password'],PDO::PARAM_STR);
You are trying to match the hashed value in the database, with a user inputted password (which is not hashed).
You should simply remove the AND password = ? and bindValue for it. That way it pulls a matching username entry from the db, and THEN does password_verify to determine if the user inputted password, matches:
$username = trim($_POST['username']);
$password = trim($_POST['password']);
$stmt = $dbh->prepare("SELECT * FROM USERS WHERE username = ?");
$stmt->bindValue(1, $username, PDO::PARAM_STR);
$stmt->execute();
$selected_row = $stmt->fetch(PDO::FETCH_ASSOC);
if(!password_verify($password, $selected_row['password'])) {
NewUser();
}
Side note: Although I'm not sure you really WANT to make a new user if they simply typed in the wrong password??? Surely you would handle that differently. Telling them they entered a wrong password and should try again.
EDIT
Also in your NewUser function you have this:
$stmt = $dbh->prepare("INSERT INTO USERS(fullname, username, email, password)
VALUES('$fullname', '$username', '$email', '$hashed_password')");
It should be this:
$stmt = $dbh->prepare("INSERT INTO USERS(fullname, username, email, password)
VALUES(?, ?, ?, ?)");
// ...
$stmt->bindValue(4,$hashed_password,PDO::PARAM_STR);// <- use $hashed_password
I'm building a simple login script and I am able to register and login no problem. However I am now trying to add a "Forgotten password" feature and I can't figure out why it's not working.
I am able to update the password in the mysql table using the same sha512 and salting method I use in my registration script but after its updated I can no longer login.
The login function that runs when a user tries to login is as follows:
if ($stmt = $mysqli->prepare("SELECT userID, firstName, pWord, salt FROM users WHERE email = ? AND conf = 1 LIMIT 1")) {
$stmt->bind_param('s', $email); // Bind "$email" to parameter.
$stmt->execute(); // Execute the prepared query.
$stmt->store_result();
// get variables from result.
$stmt->bind_result($user_id, $firstName, $db_password, $salt);
$stmt->fetch();
// hash the password with the unique salt.
$password = hash('sha512', $password . $salt);
if ($stmt->num_rows == 1) {
// Check if the password in the database matches
// the password the user submitted.
if ($db_password == $password) {
... // Log user in
}
}
}
The password part of my registration script:
$random_salt = hash('sha512', uniqid(openssl_random_pseudo_bytes(16), TRUE));
// Create salted password
$password = hash('sha512', $password . $random_salt);
// Insert the new user into the database
if ($insert_stmt = $mysqli->prepare("INSERT INTO users (firstName, lastName, email, pWord, salt, accConf, conf) VALUES (?, ?, ?, ?, ?, ?, 0)")) {
$insert_stmt->bind_param('ssssss', $firstName, $lastName, $email, $password, $random_salt, $confirmation);
$insert_stmt->execute();
... // Do something }
The password part of my reset script:
$random_salt = hash('sha512', uniqid(openssl_random_pseudo_bytes(16), TRUE));
// Create salted password
$password = hash('sha512', $password . $random_salt);
// Update the user's password
if ($update = $mysqli->prepare('UPDATE users SET pWord = ?, salt = ? WHERE email = ?')) {
$update->bind_param('sss', $password, $random_salt, $email);
$update->execute();
... //Do something }
I can see that in the database, the password is updating but when I try to login with the new password, my "Invalid login details error is showing up.
Is there a reason that my passwords would not work after updating?
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am new to PHP and I have tried to create a user database system. User registration is working but user Authentication isn't working.
Here is the Registration code:
<?php
$con=mysqli_connect("localhost","root","pass","userdb");
$username = $_POST['username'];
$phone_no=$_POST['phone_no'];
$emailid=$_POST['emailid'];
$password=$_POST['password'];
$statement= mysqli_prepare($con, "INSERT INTO user (username, phone_no, emailid, password ) VALUES(?, ?, ?, ?) ");
//string integer string string siss
mysqli_stmt_bind_param($statement, "siss" , $username, $phone_no, $emailid, $password);
mysqli_stmt_execute($statement);
mysqli_stmt_close($statement);
mysqli_close($con);
?>
Here is the Login Code:
<?php
$con=mysqli_connect("localhost","root","pass","userdb");
$usernm = $_POST['username'];
$pwd=$_POST['password'];
$statement= mysqli_prepare($con, "SELECT * FROM user WHERE username = ? AND password = ?");
//string string ss
mysqli_stmt_bind_param($statement, "ss" , $username, $password);
mysqli_stmt_execute($statement);
mysqli_stmt_store_result($statement);
mysqli_stmt_bind_result($statement, $user_id, $username, $phone_no, $emailid, $password );
$user = array();
while(mysqli_stmt_fetch($statement)){
$user[username]=$username;
$user[phone_no]=$phone_no;
$user[emaild]=$emailid;
$user[password]=$password;
if($usernm==$username && $pwd==$password){
echo"success";
} else {
echo "error";
}
}
mysqli_stmt_close($statement);
mysqli_close($con);
?>
This is possibly your problem
$usernm = $_POST['username']; //<-- $usernm != $username used in bind param
$pwd=$_POST['password']; //<-- ditto $password & $pwd
$statement= mysqli_prepare($con, "SELECT * FROM user WHERE username = ? AND password = ?");
//string string ss
mysqli_stmt_bind_param($statement, "ss" , $username, $password);
Change to this and see if that helps
$usernm = $_POST['username']; //<-- $usernm != $username used in bind param
$pwd = $_POST['password'];
$statement= mysqli_prepare($con, "SELECT * FROM user WHERE username = ? AND password = ?");
//string string ss
mysqli_stmt_bind_param($statement, "ss" , $usernm, $pwd);
I see that you are not hashing the password before you store it onto your database. This is bad practice. Can I suggest you have a look at password_hash() and password_verify()
Leaving passwords unhashed allows internal staff the possibility of hacking user accounts.
I have a PHP page that registers and logs in users. When I enable sha1, the user gets created and the encrypted password is stored in the DB, but they cannot log in. When I comment out the line to encrypt in both the user creation section as well as the login section, everthing works. Here is my code to create the user:
function add_member($nick_name, $email_address, $password) {
global $db;
$password = sha1($password);
$query = "INSERT INTO members
(nick_name, email_address, password)
VALUES
('$nick_name', :email_address, :password)";
$statement = $db->prepare($query);
$statement->bindValue(':email_address', $email_address);
$statement->bindValue(':password', $password);
$statement->execute();
$statement->closeCursor();
}
Here is my code to validate the user:
function is_valid_member($email_address, $password) {
global $db;
$password = sha1($password);
$query = "SELECT member_ID
FROM members
WHERE email_address = :email_address AND password = :password";
$statement = $db->prepare($query);
$statement->bindValue(':email_address', $email_address);
$statement->bindValue(':password', $password);
$statement->execute();
$valid = ($statement->rowCount() == 1);
$statement->closeCursor();
return $valid;
}
Again, when I comment out the "$password = sha1($password);" in both sections, everything works but the password is clear text.
Thanks!
try to debug like this, echo your $password = sha1($password); and check your database entry, might be your datatype length truncated some text in stored password