issue with password_verify() - php

So i am a newbie in php.
I have database with a pseudo and pwd table, the passwords are crypted with password_hash.
This is how i send new user in my database :
<?php
$options = [
'cost' => 8,
'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM),
];
$pwd = password_hash($pwd, PASSWORD_BCRYPT, $options);
$insert_query = "insert into user values ('$pseudo','$pwd','$mail')";
$mysqli->query($insert_query);
It's working, then when i want to log as user wich is in the database, i searh the password associated with the pseudo i write in the form, once i have the password i use it with the noon crypted password (the one i get by POST)
$options = [
'cost' => 8,
'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM),
];
$pwd2 = password_hash($pwd, PASSWORD_BCRYPT, $options);
$sql_log = "select mdp from user where pseudo ='$pseudo'";
$mysqli->multi_query($sql_log);
if($res = $mysqli->use_result()) {
while($row = $res->fetch_row()) {
echo $row[0]."<br/>";
}
$res->close();
echo $pwd2."<br/>";
echo $pwd."<br/>";
if(password_verify($pwd,$row[0])) {
$mysqli->close();
$_SESSION['pseudo'] = $pseudo;
die("<script>location.href = 'homepage.php'</script>");
}
else
echo "putin";
}
But it's not working, ive read other topics about it but nothing helps me.

Ok i've found my problem, i don't know if it will be usefull for others or if i make understandable but i was really dumb.
while($row = $res->fetch_row()) {
echo $row[0]."<br/>";
}
$res->close();
echo $pwd2."<br/>";
echo $pwd."<br/>";
if(password_verify($pwd,$row[0])) {
$mysqli->close();
$_SESSION['pseudo'] = $pseudo;
die("<script>location.href = 'homepage.php'</script>");
}
i created row in the while and when i check his value out of the while it returns 0, so the second argument that i was passing in password_verify was null...
ty

Related

Need help reading/fixing login.php with Angular and Hashed Passwords

I recently integrated a basic login/register function on my website and need help understanding my login.php code. The basic tutorial I used for the login/register page didnt include password hashing which I am currently trying to integrate myself. Everything was working 100% as expected until I decided to add password hashing. I'm very new to php and how it works so I dont quite get why my code isn't working, but I understand the basic concept/workflow of hashing passwords which is answered in other questions.
A few notes: register is working fine with storing hashed passwords and database connection is successful. Also I have an api service that calls my login.php (code included) which could be the issue.
I tested my SQL querySELECT *, password FROM users where email='jim#gmail.com'and it successfully returns 1 user with all columns.
Edit: I understand this is not SQL injection proof, that is my next step. I am trying to do this correctly, but forgive me if my current code doesn't handle passwords correctly, it is part of the learning process. (this is not a live website)
Applicable Code:
Login.php
<?php
include_once("database.php");
$postdata = file_get_contents("php://input");
$request = json_decode($postdata);
if(isset($postdata) && !empty($postdata)){
$pwd = mysqli_real_escape_string($mysqli, trim($request->password));
$email = mysqli_real_escape_string($mysqli, trim($request->username));
$sql = "SELECT *, password FROM users where email='$email'";
if($result = mysqli_query($mysqli,$sql)){
$rows = array();
while($row = mysqli_fetch_assoc($result)){
$rows[] = $row;
}
if(password_verify($pwd, $rows['password'])){
echo json_encode($rows);
}
}
else{
http_response_code(404);
}
}
?>
I have tried to use both $row and $rows on line password_verify($pwd, $rows['password']) just in case I dont understand the retrieved object type.
Register.php
<?php
include_once("database.php");
$postdata = file_get_contents("php://input");
if(isset($postdata) && !empty($postdata)){
$request = json_decode($postdata);
$name = trim($request->name);
$pwd = mysqli_real_escape_string($mysqli, trim($request->pwd));
$email = mysqli_real_escape_string($mysqli, trim($request->email));
$hash = password_hash($pwd, PASSWORD_BCRYPT);
$sql = "INSERT INTO users(name,password,email) VALUES ('$name','$hash','$email')";
if ($mysqli->query($sql) === TRUE) {
$authdata = [
'name' => $name,
'pwd' => '',
'email' => $email,
'Id' => mysqli_insert_id($mysqli)
];
echo json_encode($authdata);
}
}
?>
api.service.ts (shortened)
public userlogin(username, password) {
//alert(username)
return this.httpClient.post<any>(this.baseUrl + '/login.php', { username, password })
.pipe(map(Users => {
this.setToken(Users[0].name);
this.getLoggedInName.emit(true);
return Users;
}));
}
public userregistration(name,email,pwd) {
return this.httpClient.post<any>(this.baseUrl + '/register.php', { name,email, pwd })
.pipe(map(Users => {
return Users;
}));
}
I dont completely understand how the api service is listening for output from login.php but it seems like echo json_encode($rows); line from login.php is the output??
Many thanks in advance for any tips, advice, or solutions!
Well, I figured it out...being new to php, I had a difficult time toubleshooting/debuging. It turns out that the data type for $rows would return null if I tried to reference $rows['password], but $rows is the correct datatype to return my User object. Anyone know why that is?
My solution is to fetch 2 results and create one for the password and one for the user object because running mysqli_fetch_assoc($result); multiple times attempts to fetch the next row in the result-set. I'm not sure if this is good programming practice so feel free to comment your thoughts on this method.
NOTE: THIS CODE IS NOT SQL INJECTION PROOF, DO NOT BLATANTLY IMPLEMENT WITHOUT FURTHER PDO STATEMENTS. AS OTHERS HAVE STATED, PASSWORDS SHOULD NOT BE HANDLED DIRECTLY IN THIS WAY.
login.php
<?php
include_once("database.php");
$postdata = file_get_contents("php://input");
$request = json_decode($postdata);
if(isset($postdata) && !empty($postdata)){
$pwd = mysqli_real_escape_string($mysqli, trim($request->password));
$email = mysqli_real_escape_string($mysqli, trim($request->username));
$sql = "SELECT * FROM users where email='$email'";
if($result = mysqli_query($mysqli,$sql)){
//$passchk = mysqli_fetch_assoc($result);
$rows = array();
while($row = mysqli_fetch_assoc($result)){
$rows[] = $row;
}
if($result2 = mysqli_query($mysqli, $sql)){
$passchk = mysqli_fetch_assoc($result2);
if (password_verify($pwd, $passchk['password'])){
echo json_encode($rows);
}
}
}
else{
http_response_code(404);
}
}
?>

How can I add a number to value if already exist in CodeIgniter

In my register form I have an input which is unique but if more than two users would like to create an exact username I would like for the second username created to have a number after the typed value.
For example we have two users:
username 1: codelover
username 2: codelover2 and so on.
I currently have this in my controller:
// Create Page Data Array
$data = array(
'first_name' => strip_tags($this->input->post('first_name')),
'last_name' => strip_tags($this->input->post('last_name')),
'email' => strip_tags($this->input->post('email')),
//'username' => strip_tags($this->input->post('username')),
'ip_address' => $this->input->ip_address(),
'genre' => $this->input->post('genre'),
'slug' => $slug,
'status' => 'active',
/* 1-Founder, 2-Administrator, 3-Editor, 4-Author , 5-Contributor , 6-Subscriber , 7-Banned, 8-Suspended */
'role' => 'Subscriber',
'password' => strip_tags(password_hash($this->input->post('password'), PASSWORD_DEFAULT)),
'password2' => strip_tags(password_hash($this->input->post('password2'), PASSWORD_DEFAULT)),
);
// Is this the right approach of doing this?
$i = 0;
while($this->input->post('username') != 0){
$i++;
$data['username'] = strip_tags($this->input->post('username'.'.'.$i));
}
//Check if username and/or email already exist.
$existent_username = $this->User_model->existent_username($this->input->post('username'));
$existent_email = $this->User_model->existent_email($this->input->post('email'));
if (!empty($existent_username) || ($existent_email)) {
// Create Message
$this->session->set_flashdata('error', 'Username and/or Email already exist. Try again.');
// Redirect to pages
redirect('users/register');
} else {
// Add User
$this->User_model->add($data);
and this in my model which checks if username already exists:
public function existent_username($username) {
$query = $this->db->get_where($this->table, array('username' => $username));
return $query->row_array();
}
This is what I'm trying to do but in CodeIgniter:
if(empty($existent_username)){
$query = mysqli_query($con, "SELECT username FROM users WHERE username = '$username'");
$i = 0;
// If username already exists, add number to username
while(mysqli_num_rows($query) != 0){
$i++;
$username = $username ."." . $i;
$query = mysqli_query($con, "SELECT username FROM users WHERE username = '$username'");
}
}
First of all
// Is this the right approach of doing this?
$i = 0;
while($this->input->post('username') != 0) {
$i++;
$data['username'] = strip_tags($this->input->post('username'.'.'.$i));
}
This is wrong, its seems to me you are running an infinite loop here. I did not even understand why you need it. If you users can provide multiple username then get the input fields value first then run the loop.
Now about the main question,
you should the get all the existing usernames thats partially matches with the provided username. then generate the username and check the username already existed or not. If not then that's the username. like this.
$username = $this->input->post('username');
$existent_username = $this->User_model->existent_username($username));
if (!empty($existent_username)) {
$partially_matched_usernames = $this->db->select('username')->like('username', $username, 'after')->from('users')->get()->result_array();
$usernames_array = array_column($partially_matched_usernames, 'username');
// now generate the username
$i = 1;
while(true) {
if( ! in_array($username.$i, $usernames_array)) {
$username = $username.$i;
break;
}
$i++;
}
echo $username;
}
I did not run this code, so there could be any error. I think you will able to fix that by yourself.

Phalcon php hash same password produces multiple result

I use this statement to hash the password with Phalcon:
$hashedPassword= $this->security->hash($password)
but this statement returns different results with the same password.
Example:
Set $password=123
I get $hashedPassword with the following values:
$2a$08$T2Rf9IcQHTj7TpY.gsfGiexZ35/KK9kS3fLElxaw8LGXhjnE01f5K
and
$2a$08$E2mjApECMbRKQFZodgLkEOpDLSV/tEjTe1HV3q2LLG9UINj9M9GBm
and
$2a$08$aZmgsMmG2xRueVzP6tkx2ucWGPZMzUwIccXbLJnqoRwDsSnT4zc.q
Here is the code I use for checking user's password,
please let me know what am I missing.
if ($this->request->isPost() == true)
{
$email = $this->request->getPost ("email");
$password = $this->request->getPost ("password");
$conditions = "email = ?1 AND admin = ?2";
$parameters = array(1 => $email, 2 => 1);
$users = Users::findFirst(array(
$conditions,
"bind" => $parameters
));
if($users)
{
$security = new Phalcon\Security();
$checkHashValue = $security->checkHash($password, $user->password);
if($checkHashValue)
{
$this->flash->success($users->fullname);
}
else
{
//Print debug information
$hash = $security->hash($password);
$checkHash = $security->checkHash($password, $hash);
$this->flash->error("Password: ". $password.
"<br/>Hash: " . $hash . "<br/>Check Hash: " . $checkHash .
"<br/>Check HashValue: ". $checkHashValue);
}
}
else
{
$this->flash->error($password);
}
}
SOLUTION: I have a typo in my variable "user" instead of "users".
That's how it is supposed to work. It creates a random hash each time. To check the password use security->checkPassword()
SOLUTION: I have a typo in my variable "user" instead of "users".

PHP login using Array Not DB

As a practice, I am trying to create a script to log a user in using array.
So I have created a associate multidimensional array which holds 'user' and 'password',
The idea is to use this array to compare data entered by the user through a HTML form.
The problem I am having is that, the password entered by the user is checked against all the password stored in array not the only one the password belongs to. So I am struggling with a logic to check the password entered by the user with the values stored in array, one by one and not as a whole.
My script:
<?php
$data = Array();
$data['email'] = $_POST['email'];
$data['pass'] = $_POST['pass'];
$data['passM'] = $_POST['passM'];
$users = Array(
'tomasz' => '123',
'mario' => 'abc',
);
if($_SERVER['REQUEST_METHOD']=='POST'){
$hello='';
foreach($users as $u => $p){
if($data['passM'] == $p){
header("Location: ../home.php");
}else{
echo "nooooo";
}
}
var_dump($users);
var_dump($data['email']);
var_dump($data['pass']);
var_dump($data['passM']);
}
Could anyone please suggest a solution?
Try This code, I hope you will find answer to your question.
$data = Array();
$data['email'] = $_POST['email'];
$data['pass'] = $_POST['pass'];
$data['passM'] = $_POST['passM'];
//var_dump($_POST);
$users = Array(
'tomasz' => '123',
'mario' => 'abc',
);
if($_SERVER['REQUEST_METHOD']=='POST'){
$hello='';
if(in_array($data['passM'],$users)){
echo "Found";
}else{
echo "nooooo";
}
}
Check the username first, then the pass for these user.
Right now I don't see any logic that provides any way of knowing what user to check against. If you knew what user was logging in you could check that the username of the array was the same as the username the form provided.
$data['user'] = $_POST['user'];
foreach($users as $u => $p){
if($u == $data['user']){
if($data['passM'] == $p){
header("Location: ../home.php");
}else{
echo "nooooo";
}
}
}
I assume you know which user tries to log in.
So, you could just check if this user exists and if the password is correct.
$data['user'] = $_POST['user'];
if(array_key_exists($data['user'], $users) && $data['passM'] == $users[$data['user']]) {
header("Location: ../home.php");
} else {
echo "nooooo";
}
Well Mr. Tomari in_array() method look for only value in array. if you have stored you email in array as value then no issue. if you have store 'email' as key and 'passm' as value of the that email then you have to use this code:
if($_SERVER['REQUEST_METHOD']=='POST'){
$hello='';
if(array_key_exists($data['email'],$users) && in_array($data['passM'],$users)){
echo "Found";
}else{
echo "nooooo";
}
}

PHP: Hashing code not working any longer?

I used this hash function for a while (got it from the internet). The thing is it used to work immediately but now it is complaining about a paramter. The following is the code:
function generateHash($plainText, $salt = null)
{
if ($salt === null)
{
$salt = substr(md5(uniqid(rand(), true)), 0, SALT_LENGTH);
}
else
{
$salt = substr($salt, 0, SALT_LENGTH);
}
return $salt . sha1($salt . $plainText);
}
So I would use this code in the method call:
validateUserInput($userid, $pass);
and validateUserInput is:
function validateUserInput($username, $password)
{
//$username = mysql_real_escape_string($username);
//$password = mysql_real_escape_string($password);
if(!$username || !$password)
{
//$errors['credentials'] = 'Missing Credentials!';
//$_SESSION['errors_array'] = $errors;
//echo $errors['credentials'];
header("LOCATION:XXXXXXX.php");
}
$local_salt = generateHash($password);
//echo $local_salt;
$groupid;
if($username != null && $password !=null)
{
connectToServer();
$result = mysql_query("SELECT * FROM users WHERE hashkey = '{$local_salt}'");
while($row_access = mysql_fetch_array($result))
{
$groupid = $row_access['groupid'];
}
if(!isset($result))
{
$errors['not_found_user'] = 'No Users Found with Provided Credentials!';
//$_SESSION['errors_array'] = $errors;
$userfound = 0;
$_SESSION['user_available'] = $userfound;
}elseif(isset($result)){
$_SESSION['user_logged'] = array('username' => $username, 'password' => $password, 'salt' => $local_salt, 'groupid' => $groupid);
$userfound = 1;
//echo "stored";
$_SESSION['user_available'] = $userfound;
}
}
}
finally the error is:
Warning: substr() expects parameter 3 to be long, string given in /home/XXXX.php on line 64
This is pointing to the function generateHash()
The error itself tells you everything. The constant SALT_LENGTH is not a long. I suspect it's not defined at all, so PHP converts the bare string to a string ("SALT_LENGTH") and passes that to substr(), which complains.
That being said... This code is dangerously wrong:
if(!isset($result)): Really? This condition will always be false because $result will always be set (unless you run into a problem with mysql_query(), but that doesn't tell you anything about the valididty of the login). And since mysql_query() never returns null, no logins will ever be rejected.
This query:
SELECT * FROM users WHERE hashkey = '{$local_salt}'
Is invalid. $local_salt = generateHash($password);. From the generateHash function, if a salt is not given, one will be randomly created for you. Thus, every call to generateHash will generate a new hash, which means it can't be compared to anything in the database.
On the basis of the two (very) egregious mistakes above, I would throw away this piece of code for good.
The correct way to check for a valid hash when a salt is used is something like:
$_SESSION['user_logged'] = null;
// fetch hashed pw from db, where username is the submitted username
$result = mysqli_query("SELECT hash FROM users WHERE username = '{$username}'");
if ($result->num_rows != 0)
{
$row = $result->fetch_assoc();
$hash = $row['hash'];
$salt = substr($hash, 0, SALT_LENGTH); // extract salt
if (generateHash($password, $salt) == $hash)
{
// login successful.
$_SESSION['user_logged'] = $username; // don't store passwords here
}
}
// if $_SESSION['user_logged'] is not set, the login failed
if (!isset($_SESSION['user_logged']))
{
// you *don't* want to tell people which one (login or pw) is invalid
echo 'Invalid login or password';
}
Note: It's very important that the SALT_LENGTH is at most 32, or this won't work because of the way generateHash() is implemented.
Clearly SALT_LENGTH is not an integer. Find where it's defined and correct this.
Instead of making a new hashing function each time you write an application , you should utilize the one provided to you by php: crypt() ( i would recommend to go with any blowfish or sha256+ hash ).
And when selecting information from database, you should select it by username and then, with php, check if hash fits the password.

Categories