Trouble with PHP and Mysql queries using md5 encryption - php

I am using a normal php/mysql insert query and use md5 to encrypt the password
This is the INSERT query:
$sql = mysql_query("INSERT INTO user (username, password, role, approved) values ('".$username."', '".md5($password)."', 'user', '0')");
And this is my SELECT query which I use for my login check:
$sql = "SELECT id, username, password, role, approved FROM user WHERE username = '".$username."' AND password = '".md5($password)."'";
$result = mysql_query($sql);
But when I check the inserted password and the login password, it returns 2 different values even though if I give same values.
Can anybody help me to fix this problem?

Many of the typical caveats here apply... it can't hurt to mention them.
First, vanilla md5 for your password hashing is certainly not the best way to secure your user password within the database. There are numerous questions on stackoverflow that document better approaches, and though there are differences of opinion, they are all more secure that a regular md5, unsalted hash.
Secure hash and salt for PHP passwords
Why not use AES for password encryption in PHP?
Also, you are doing no sanitization of your sql inputs, leaving your database open to sql injection attacks. A meddlesome user could manipulate your user insert to drop tables or modify your data structure. You need to escape these values using mysql_real_escape_string() or adopt a totally different database access system like PDO that has parameterized sql.
How can I prevent SQL injection in PHP?
That being said, your query should check for the existence of a User row that has the correct username and password, usually achieved by doing a COUNT query first and ensuring that the user is present in the database with valid login creds.
You should ensure that your database columns are proper length and datatype to store the hashes for passwords. Truncation of either could destroy the data.
I hope this helps - SQL injection can be especially nasty!

Assuming $username and $password are in fact the same... have you checked to make sure the on table users the password column character length is big enough to hold the whole MD5 hash?
Got an example of the calculated and store MD5 hashes?

Related

SQL Injection on md5() [duplicate]

Ok,
So, i'm a little unsure on this.
I have a url parameter username.
and I have this statement
SELECT * FROM users WHERE user_hash = md5($_GET['username'])
Is this secure?
Upon account creation an md5 hashed version of the username and the password are stored.
I'm confused as this seems so simple, if md5 stops sql injection why isn't username and password always saved in hash form?
Yes, this will avoid SQL injection, because md5() always returns a string of hex code.
But it isn't a general solution to SQL-injection. You would have to encode almost all the data in your tables in MD5 format. For instance,
$sql = "UPDATE users SET fullname = '" . md5($_GET['fullname']) . "'
WHERE id = '" . md5($_GET['id']) . "'";
But MD5 is a one-way hash, so there would be no way of displaying the full name that was stored this way.
Short answer is no, MD5 does not prevent SQL injection. Proper coding is the best way to handle this.
Reason being in this case is that your query string parameter is allowing direct access to the sql. E.g. what if the user sends you:
?username=%27a%27);DROP%20TABLE%20users;%20--
That fakes the MD5 function out and drops the users table. Of course they have to know somethings about your database in order to do this. The correct way to handle it would be to MD5 the value before it went into the SQL. In PHP it would be something like this:
$username = $GET['username'];
$hashed_username = md5($username);
$sql = "SELECT * FROM users WHERE user_hash = '$hashed_username'"
Or the best solution would be to use bound variables in queries where you let the SQL libraries handle the translation. If you are using PHP, look into PDO bindParam, http://php.net/manual/en/pdostatement.bindparam.php
BTW, your SQL won't work because you would need to quote (') the get variable in the SQL.
I'm confused as this seems so simple, if md5 stops sql injection why isn't username and password always saved in hash form?
The reason is because simple operations like searching for a user with a particular name would be impossible.
SELECT * FROM users where user LIKE '%cat%'
Would find all users with the word cat within it.
Also simple administration would be impossible, you can't even view a roster of all users.

Does md5 stop SQL Injection

Ok,
So, i'm a little unsure on this.
I have a url parameter username.
and I have this statement
SELECT * FROM users WHERE user_hash = md5($_GET['username'])
Is this secure?
Upon account creation an md5 hashed version of the username and the password are stored.
I'm confused as this seems so simple, if md5 stops sql injection why isn't username and password always saved in hash form?
Yes, this will avoid SQL injection, because md5() always returns a string of hex code.
But it isn't a general solution to SQL-injection. You would have to encode almost all the data in your tables in MD5 format. For instance,
$sql = "UPDATE users SET fullname = '" . md5($_GET['fullname']) . "'
WHERE id = '" . md5($_GET['id']) . "'";
But MD5 is a one-way hash, so there would be no way of displaying the full name that was stored this way.
Short answer is no, MD5 does not prevent SQL injection. Proper coding is the best way to handle this.
Reason being in this case is that your query string parameter is allowing direct access to the sql. E.g. what if the user sends you:
?username=%27a%27);DROP%20TABLE%20users;%20--
That fakes the MD5 function out and drops the users table. Of course they have to know somethings about your database in order to do this. The correct way to handle it would be to MD5 the value before it went into the SQL. In PHP it would be something like this:
$username = $GET['username'];
$hashed_username = md5($username);
$sql = "SELECT * FROM users WHERE user_hash = '$hashed_username'"
Or the best solution would be to use bound variables in queries where you let the SQL libraries handle the translation. If you are using PHP, look into PDO bindParam, http://php.net/manual/en/pdostatement.bindparam.php
BTW, your SQL won't work because you would need to quote (') the get variable in the SQL.
I'm confused as this seems so simple, if md5 stops sql injection why isn't username and password always saved in hash form?
The reason is because simple operations like searching for a user with a particular name would be impossible.
SELECT * FROM users where user LIKE '%cat%'
Would find all users with the word cat within it.
Also simple administration would be impossible, you can't even view a roster of all users.

How to add md5 hash of a password in phpmyadmin 4.1.6?

I am new to phpmyadmin. I wanted to store md5 hash of password in database table without using help of php code. So I found on solution here . But I could not find the option for 'function' in phpmyadmin-4.1.6. How can I achieve my goal?
For Encrypting password your database with md5() use this query in SQL.
UPDATE table_name SET column_name = MD5('password') WHERE 'column_name' = column_value
Here password in MD5 function is the one which you want to encrypt in your database
For ex:
If i have a table called "userdetails" columns for id = "user_id", for email = "email_id", & for password = "pass" and my password is "12345678"
UPDATE userdetails SET pass = MD5('12345678') WHERE 'user_id' = 1
You will get the output printed like 1 row affected in 0.0023 sec
And your password of user_id = 1 will be encrypted as25d55ad283aa400af464c76d713c07ad
If you now want to check what is your password simply copy the code of password column and google for md5 decrypter or go to this link: http://md5decrypt.net/en/ and paste the code and tap on the decrypt button. You will get your password in simple text.
Note: md5 encryption is not advisable for sensitive informations & data(s). But if you are just learning database and just simply creating one database for learning purpose you can use md5 encryption.
It is not phpmyadmin function, it is mysql function, to store password use this code:
To update password
UPDATE table_name SET column_name= MD5('password) WHERE column_name=column_value;
To insert password into table
INSERT INTO table_name(column_name) VALUES MD5('password');
MySql does not have any appropriate functions to hash a password. MD5 is ways too fast and one should include a random salt. Because of the salt you cannot just recalculate the hash and compare it with the stored hash.
That said, the hashing of passwords should not be done directly in SQL, instead one should use a server-side language. PHP offers the functions password_hash() and password_verify().

PHP MD5 not working correctly

So I'm using md5 to encode and decode passwords when users register and login, however the password in my database doesn't match the password used when logging in even though I know they are the same word:
This is what is in my database
098f6bcd4621d373cade4e832
And this is what using md5 on the password used on the login screen gives me
098f6bcd4621d373cade4e832627b4f6
As you can see there are 7 additional characters, but I can't tell why they aren't the same. Here is the script used for inserting the user details into the database on registering
$qry = "INSERT INTO Members(fname, lname, fullname, email, login, passwd, bad_league_id)
VALUES('$fname','$lname',0,'$email', '$login','".md5($_POST['password'])."',0)";
$result = #mysql_query($qry);
And here is how my login form compares the values
$qry="SELECT * FROM Members WHERE login='$login' AND passwd='".md5($_POST['password'])."'";
$result=mysql_query($qry);
On another note, I am currently in the process of transferring over from mysql to mysqli so forgive the use of mysql as I know its deprecated.
By default, the hash generated by the MD5() function is 32 characters long. The datatype of the passwd column is currently VARCHAR (25), which means it will only store up to 25 characters, 7 characters less than the actual value.
To fix this, you will need to change the datatype of the passwd column to be able to store the correct length, e.g. VARCHAR (32).

why does the MySQL password() function fail in the user login verification?

the code below is unable to find a matching record when it "should":
$result = mysql_query("SELECT * FROM $tbl_Name WHERE userID = '$userID' AND userKey = password('$user_password')"); // where $user_password = god12345 for example
userID comparison works fine if I remove the AND....
password comparison fails above. I am certain that when the user was created the password was hashed using password().
If I set $user_password to the actual hash stored in the data and compare literals, it works.
... AND userKey = '$user_password' // where $user_password = *29A59C23ED11F7E2510 for example
This is destroying me. Obviously I don't want to compare literals.
You can't expect password() to work when it's being interpreted as text.
Try:
$result = mysql_query("SELECT * FROM $tbl_Name WHERE userID = '$userID' AND userKey = '" . password('$user_password') . "'");
I'm not 100% sure if this will answer the question but here goes.
When a user signs up you hash the password, so on the database the password is a crazy looking string. This can't be reversed so if you want to check if a password entered is right you'll have to hash the new input from the user login in and then compare that hash with the one on your database.
Does that help?
Instead of using the mysql PASSWORD function which is in my opinion very weak, try to save your passwords into the database encrypted by php. For example:
$password = md5('MyApplicationSalt'.$user['creationdate'].$newpassword);
mysql_query('UPDATE users SET password = "'.$password.'" WHERE id = '.$user['id']);
The main reason to do this is:
Creating a much stronger hash of your password: Using PASSWORD from mysql means that there is no additionnal salting done. If someone were to create a table of all possible passwords from 1-10 characters and then PASSWORD() them and compare to your stolen data, they could reverse the passwords. Using a salt will prevent this in the event that only your data is stolen. Obviously, if code is stolen, it doesn't protect it, the person can search for the hash salt and still reverse it.
Another reason would be to be able to log correctly what you are doing. For example, try logging your SQL query using the method before and check if the data is always the same. It should... if it's not it might be that you have special characters laying somewhere in your string when comparing or when updating...
Good luck
Thanks to everyone who answered, particularly Mathieu who inspired me to realize my error.
userKey VARCHAR(20) BINARY NOT NULL
As of MySQL 4.1, the PASSWORD() function has been modified to produce a longer 41-byte hash value.
So the problem was... the value stored in the dbase when I created the user was limited to 20 characters while the inputted value for login comparison was a longer 41-byte hash value.
Prior to MySQL 4.1, password hashes computed by the PASSWORD() function are 16 bytes long.
I was expecting the varchar(20) to hold all of the hash since the book I'm using as a guide was written in 2000....time to buy a new book.

Categories