I'm writing a login form, and it converts the given password to an MD5 hash with md5($password), then matches it to an already-hashed record in my database. I know for sure that the database record is correct in this case. However, it doesn't log me in and claims the password is incorrect.
Here's my code:
$password = mysql_real_escape_string($_POST["password"]);
...more code...
$passwordQuery = mysql_fetch_row(mysql_query(("SELECT password FROM users WHERE email = '$userEmail'")));
...some code...
elseif(md5($password) != $passwordQuery)
{
$_SESSION["noPass"] = "That password is incorrect.";
}
...more code after...
I tried pulling just the value of md5($password) and that matched up when I visually compared it. However, I can't get the comparison to work in PHP. Perhaps it is because the MySQL record is stored as text, and the MD5 is something else?
$passwordQuery contains and array with the hash, and not just the hash.
Instead of
elseif(md5($password) != $passwordQuery)
try
elseif(md5($password) != $passwordQuery[0])
It looks to me like you're comparing a string (the result from $_POST) with an array (the result of mysql_fetch_row). You'll probably want something like:
if (md5($password) != $passwordQuery['password') {
....
}
Related
This question already has answers here:
How to use PHP's password_hash to hash and verify passwords
(5 answers)
Closed 1 year ago.
Here's my code:
function login() {
//Declare variables
$username = $_POST["login"];
$password = $_POST["password"];
$client = $_POST["clients"];
//QueryDB
$servername = "localhost";
$SQLUsername = "XXXX";
$SQLPassword = "XXXX";
$dbname = "XXXX";
$conn = new mysqli($servername, $SQLUsername, $SQLPassword, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
//Set query then run it
$sql = "SELECT * FROM Users WHERE Username ='$username'";
$result = $conn->query($sql);
$row = $result->fetch_array(MYSQLI_ASSOC);
//Verify Password
if ($result->num_rows === 1) {
if (password_verify($password, $row['Password'])) {
//Build XML request
$XMLRequest = "<?xml version='1.0'?><Login><Client>".$client."</Client><LoginDetails><Username>".$username."</Username><Password>".$newhash."</Password></LoginDetails></Login>";
//Build URL
$ReplacedValues = array("NewType" => "login", "NewHash" => $XMLRequest);
$NewString = strtr($GLOBALS["params"], $ReplacedValues);
$NewUrl = $GLOBALS["link"].$NewString;
//Post to Server
header('Location: '.$NewUrl);
}
else {
echo "Password is wrong"."<br>";
echo $password."<br>";
echo $row['Password'];
}
} else {
echo "more then 1 row";
}
mysqli_close($conn);
}
My issue is that even if I hard code my password variable and Hash variable to their respective values the if condition returns false. Any idea why? The page does when it loads, loads the else condition to show me the user input password and the correct hash value from the DB. My DB is set to CHAR(255) for the password.
UPDATE**
Here is my C# discussed in the comments. This is not the complete code just up to the part of the insert statement for the DB. I am able to insert into the SQL server DB just fine.
public static string WebsiteRegister(XmlDocument XMLBody)
{
//Get SQL connection string
XmlNodeList XMLNodes = SQLConnectionMethods.EstablishSQLServerConnection("SQL");
string ConnectionString = XMLNodes.Item(0).ChildNodes[0].InnerText;
string UserName = XMLNodes.Item(0).ChildNodes[1].InnerText;
string Password = XMLNodes.Item(0).ChildNodes[2].InnerText;
//Open connnection
SqlConnection cnn = new SqlConnection(ConnectionString);
SQLConnectionMethods.OpenSQLServerConnection(cnn);
try
{
string username = XMLBody.SelectSingleNode("register/registerdetails/username").InnerText;
string pass = XMLBody.SelectSingleNode("register/registerdetails/password").InnerText;
string fname = XMLBody.SelectSingleNode("register/registerdetails/firstname").InnerText;
string lname = XMLBody.SelectSingleNode("register/registerdetails/lastname").InnerText;
string email = XMLBody.SelectSingleNode("register/registerdetails/email").InnerText;
string accountRef = XMLBody.SelectSingleNode("register/registerdetails/accountreference").InnerText;
string client = XMLBody.SelectSingleNode("register/client").InnerText;
//Build Query string
string queryString = $"Insert into [dbo].[UserAccounts] (AccountReference, FirstName, LastName, Email, Username, Pass, Client) values ('{accountRef}', '{fname}', '{lname}', '{email}', '{username}', '{pass}', '{client}')";
//Process request
using (SqlCommand myCommand = new SqlCommand(queryString, cnn))
{
string Result = (string)myCommand.ExecuteScalar();
I could not find any problem in your code here but since hashing and verifying is a process which depends on a lot of factors to be successful i would like to give you some tips so that you can check it yourself for any potential problems.
make sure you are not escaping/sanityzing the password before
hashing it. This way you're altering the stored password. Let
$password = $_POST['password'];
both when you create the account and
when you check if the password match at login.
make sure you are enclosing the hash variable in single quotes (') and not double quotes (").using double quotes makes PHP read each paired character with "$" as indivisual variables which will probably cause your code to break, USE SINGLE QUOTES INSTEAD.
Ensure the Password field in the database (that stores the hashed
password) is able to store up to 255 characters. From the documentation
it is recommended to store the result in a database column that can
expand beyond 60 characters (255 characters would be a good choice). If the field is narrower the hash will be truncated and you'll never
have a match.
As you get the user by username at login ensure that username is unique
as long as it is your primary key (in the table
definition). Good idea to check this also upon user registration and login (at php level).
echo both hash and entered
values and make sure they match the ones that were inserted and
generated during password_hash() if the database value was different
(the hash), make sure the type of its column is varchar(256), the
hash is usually 60 characters long but the hashing function is
frequently improved so that length may expand in the future.
if the entered value was different (the user password), make sure the
filtering isn't corrupting the password value.
also check if another variable has the same name as the one you're storing the password in.
If password_verify($password, password_hash($password, PASSWORD_DEFAULT))
"works", then the problem is that $row['Password'] does not contain what is expected - including not being generated correctly.
If it "doesn't work" then
another line is causing the observed behavior. Both of these
outcomes allow focusing on a refined problem set.
try changing the password from the another column that matched and copy it to your password column and enter that password to check.if it worked then there is problem with your stored password
try copying this hash to your password column
$2y$10$uDnEpQpkh9RO5tWwOrHtneLAuYMRDstRaKGZFyHubObDR0789OMO6
this is the hashed password for 123456 using bycrypt. select this password and try to verify it with password_verify(123456,$yourhashedfromdatabase) after selecting this from sql if it works then there is probably some manipulation after your data is entered and goes to the database. it it does not then check if the password that reaches the database is exactly as your typed by echoing it.
UPDATE: after you updated your code i see that while entering the password you use "Pass" column but while extracting you use "Password" column. this could be the issue
I am working on page with register and login possibilities.
It always says that the password is incorrect. What am I doing wrong?
I also tried with iterator_to_array, it doesn't work either.
$db = get_db();
$mojlogin = $_POST['login'];
$mojehaslo = $_POST['haslo'];
empty($mors);
$mors = $db->morsy->findOne(array('login' => $mojlogin, "haslo1" => $mojehaslo));
if(password_verify($mojehaslo, $mors['haslo1'])){
echo "Zalogowany!\n";
$powitanie = "Witaj ponownie, ".$mojlogin."!";
echo "<h1 class='tytul'>$powitanie</h1>";
$_SESSION["user"] = $mojlogin;
} else {
echo "Niepoprawny login lub hasło!\n";
}
As far as I can tell from your code, you request the user password and use it as a search criteria to get his account from the database, which implies that instead of storing the hash of the password, you store the password itself.
The proper way to do this is to generate hash first, store it in haslo1 field, and then use it as a second argument in the password_verify function along with the actual password in $mojehaslo as the first one. Furthermore, you only use $mojlogin in the findOne() query, because the idea is to get the hash from the database corresponding to user login and compare it to the password that was entered.
You normally want to generate your hash using password_hash function:
$hash = password_hash($password, PASSWORD_DEFAULT);
Then, after you place it in haslo1 document field, you use almost the same code as you did before:
$mors = $db->morsy->findOne([ 'login' => $mojlogin ]);
if (password_verify($mojehaslo, $mors['haslo1'])) {
// here goes your entrance code
}
Check var_dump, always.
After not getting my login, my friends told me to use:
var_dump(iterator_to_array($db->morsy->find()))
I had white space before login, because of mistakes in form.
I'm trying to store an encrypted password in MySQL and as for the register part it works as it should how ever when i try to do the login things go south.
I can not verify $_POST['password'] against the hash stored in MySQL.
I have no idea what I'm doing wrong.
Here is my register.php which works as it should:
register.php (working)
$post_password = mysqli_real_escape_string($_POST['password']);
$password_hash = password_hash($post_password, PASSWORD_BCRYPT);
mysqli_query goes here...
login.php (not working)
$con = mysqli_connect("XXX","XXX","XXX","XXX");
$post_username = mysqli_real_escape_string($con,$_POST['username']);
$post_password = mysqli_real_escape_string($con,$_POST['password']);
// Getting the stored Hash Password from MySQL
$getHash = mysqli_fetch_assoc(mysqli_query($con, "SELECT * FROM anvandare WHERE username = '$post_username'"));
$got_Hash = $getHash['password'];
// Checking if what the user typed in matches the Hash stored in MySQL
// **This is where it all goes wrong**
if (password_verify($post_password, $got_Hash)) {
echo "The posted password matches the hashed one";
}
else {
echo "The posted password does not match the hashed one";
}
When I run the code above I get the "Correct password" message by just entering the username and leaving the password field out.
What am I missing?
Actually you need to make sure that you are allowing more than 100 characters in your password column so that all the hashed password can be saved in the field. This was also happening with me, the script was correct and everything was working fine but the only mistake I was doing was that I didn't allow more than 40 characters in the password field which was the biggest error. After incrementing the maximum limit from 40 to 100, everything is working fine:)
I've got a login script that I'm just starting on. When a new password is entered it is first encrypted using MD5, then stored in the database.
When I type the username and password in my login form and submit it, I'm trying to verify the stored password against a $_POST variable like this:
$username = $_POST['username'];
$password = md5($_POST['password']);
//database stuff here
$q = mysql_query("SELECT * FROM Users WHERE username='$username'");
while ($row = mysql_fetch_array($q))
{
if ($row['password'] == $password)
{
echo "Passwords match.";
}
else
{
echo "Password is incorrect.";
echo "<br />Entered password: " . $password;
echo "<br />Stored password: " . $row['password'];
}
}
This is just in the testing stages, so the password that I'm attempting to verify is 'password', for simplicity. If I output $_POST['password'], I get password - however, if I output the MD5 hash as stored in the database and md5($_POST['password']), they do not match. The latter has extra characters. Anyone know why this is happening?
Your column type could be truncating the data when you store it.
Check that it is at least 32 characters (the size of an MD5 hash).
Also, this script is vulnerable to SQL injection.
Your field is too short. MD5 hashes have 32 hexadecimal digits.
It is possible to get tricked. Check this:
$str=md5('password');
print(strlen($str));
and the output is 32. (the string is "5f4dcc3b5aa765d61d8327deb882cf99")
Now try inserting this within html code:
<?=print(md5('password'));?>
And the output is "5f4dcc3b5aa765d61d8327deb882cf991" (33 chars)
The issue gets clearer when you insert:
<?=print(strlen(md5('password')));?>
The output is "321"
This works:
<?php print(strlen(md5('password')));?>
Despite the other answers, MD5 as an algorithm does not produce hexadecimal characters at all. MD5 is an operation that is performed on binary data. As output, it returns 16 bytes of binary data.
It's the PHP function that returns a hexadecimal string. It depends on the way you want to handle the output of the hash if this is what you want. If you store the hash as binary data you might want to use the "raw" output:
string md5 ( string $str [, bool $raw_output = false ] )
Im trying to compare a hashed password value in a mysql database with the hashed value of an inputted password from a login form.
However, when I compare the two values it says they aren't equal. I removed the salt to simply, and then tested what the outputs were and got the same values
$password1 = $_POST['password'];
$hash = hash('sha256', $password1);
...connect to database, etc...
$query = "SELECT *
FROM users
WHERE username = '$username1'";
$result = mysql_query($query);
$userData = mysql_fetch_array($result);
if($hash != $userData['password']) //incorrect password
{
echo $hash."|".$userData['password'];
die();
}
...other code...
Sample output:
7816ee6a140526f02289471d87a7c4f9602d55c38303a0ba62dcd747a1f50361| 7816ee6a140526f02289471d87a7c4f9602d55c38303a0ba62dcd747a1f50361
Any thoughts?
I was having the exact same problem. var_dump() was telling me that I had two variables with the same properties, string(128). The only way I was able to get the comparison to work was to cast the hashed values as strings:
$password1 = $_POST['password'];
$hash = (string)hash('sha256', $password1);
...
$userData = (string)mysql_fetch_array($result);
if($hash == $userData) {
//This should return true.
}
Try using strcmp. String comparisons with == or != rarely go well.
if(strcmp($hash, $userData['password']) != 0) {
//this would be where the password was incorrect.
}
It may very well be treating it as a number for some reason and failing the comparison.
Try switching != to == and switch content. Like this
if($hash == $userData['password']) //incorrect password
{
//proc login...
}
else
{
echo $hash."|".$userData['password'];
die();
}
I'm not sure why is that happening but you can be sure it will work in my case
EDIT: you did something wrong in your case. works for me
== is an object hashcode comparison, you need to use a strcmp function to compare string literals.
Not sure if you ever got this solved but I just wasted 30 minutes with the exact same problem. Turns out my mysql value had an extra space at the end. It was a test user I manually added to the database and somehow got an extra space when copying and pasting the hashed password.
Not sure if this applies to your situation or not but I thought I'd share anyway.