How to use the md5 hash? - php

Okay, so I'm learning php, html, and mysql to learn website development (for fun). One thing I still don't get is how to use md5 or sha1 hashes. I know how to hash the plain text, but say I want to make a login page. Since the password is hashed and can't be reversed, how would mysql know that the user-inserted password matches the hashed password in the database? Here is what I mean:
$password = md5($_POST['password']);
$query = ("INSERT INTO `users`.`data` (`password`) VALUES ('$password')");
I know that this snippet of script hashes the password, but how would I use this piece of code and make a login page? Any working examples would be great.
Here is my script:
<?php
session_start();
include("mainmenu.php");
$usrname = mysql_real_escape_string($_POST['usrname']);
$password = md5($_POST['password']);
$con = mysql_connect("localhost", "root", "g00dfor#boy");
if (!$con) {
die(mysql_error()); }
mysql_select_db("users", $con) or die(mysql_error());
$login = "SELECT * FROM `data` WHERE (`usrname` = '$usrname' AND `password` = '$password')";
$result = mysql_query($login);
if (mysql_num_rows($result) == 1) {
$_SESSION['logged_in'] = true;
header('Location: indexlogin.php');
exit;
}
else {
echo "Wrong username or password.";
}
?>
But I still get the else statement, "Wrong username or password. Someone help plz!"

The answer is quite simple: You have a hash in the database, so you need to hash the user-provided password to compare them.
So when the user attempts to log in, you take the $_POST['password'] or whatever, and create a hash of it. Then, you simply query the database for the hash, SELECT * FROM users WHERE password = 'hashgoeshere'
I would also recommend you read more about secure storage of passwords. For example this is a good start: You're probably storing passwords incorrectly - Coding Horror

Please use SHA1/256. MD5 is not cryptographically secure anymore and it's discouraged to use it for cryptography (it's fine for file hashes ETC).
I'm not posting code, but explaining the technique:
First, on the registration, take the SHA1/256 hash of the password and store it in the database. The next time the user logs in you take the SHA1/256 hash of the password he/she entered again and match it against the hash stored in your database. This works because the SHA1 hash for the password is semi-unique (the chances for duplicates are small) for that password.

well instead of inserting into the SQL database, assign some query into a variable and check it against the md5 given by the user

When the user tries to login using their password, you take the md5 of what they enter and compare it with what you've already stored in the database. If it matches, you know they entered the right password.

It hashes the password so it is not save in clear text
e.g mylongpassword becomes 9a995d3f6a3d69c1a9b4344bed4f2c87
Select the hashed password using the db First
$password_from_db = Select * from user where username='".$_POST['username']."'
Then password from the ($_POST['password']) should be hashed first in PHP then compared to the valued stored in the DB
<?
if (md5($_POST['password'])==$password_from_db){
return true;
}else{
return false;
}
?>

Edited
Your code seems okay.
Check if your password field in the database is at least 32 characters.
And try to execute this query (changing variables to real string) in phpMyAdmin if you use one.

You have a major crypto problem, too.
$password = md5($_POST['password']);
The problem there is that all the people with identical passwords will have identical hashes, so if (when?) someone breaks into your site, they run one dictionary attack, and then compare the hashes from the attack to the hashes from your DB. As a result, they break every single account on your site for essentially the same cost as breaking one.
At a very minimum, you should salt it, something like this:
$password = md5($_POST['user'] + $_POST['password']);
But even that has surprising weaknesses, so it's better to hash it twice, maybe like this:
$password = md5($_POST['password'] + md5($_POST['password'] + $_POST['user']));
Of course, the best way of all is to use something written by someone who knows far more about doing crypto properly than I do :)
(And remember that bad perf in your authentication system is a feature.)

Related

how to create md5 password in php and save to database?

I have an existing database with users, each users password is stored as an MD5 hash.
Im trying to create a login form using PHP (Which im very new too) only I cant seem to get it to work, I know my username and password is correct yet I still receive the error that its wrong, Have I got to convert my password input to MD5 before checking the username in the table?
I currently have...
if (isset($_POST['register'])){
$name = $_POST['name'];
$username = $_POST['username'];
$password = $_POST['password'];
$confirm_password = $_POST['confirm_password'];
if ($password == $confirm_password) {
$query = mysqli_query($db, "INSERT INTO users (name, username, password) VALUES ('$name', '$username', MD5('".$password."'))");
//$query="INSERT INTO ptb_users (id,user_id,first_name,last_name,email )VALUES('NULL','NULL','".$firstname."','".$lastname."','".$email."',MD5('".$password."'))";
echo 'OK.';
} else {
echo 'Error.';
}
}
It is possible to use md5 as your encryption algorithm, but I would suggest to use better alternatives. Take a look here, this is the official php documentation. Just using the basic example on that page would be more secure than md5
$password = password_hash("rasmuslerdorf", PASSWORD_DEFAULT);
Back to your question, yes, if the password is saved as an md5 hash into the database you have to convert the password in input with the md5 function and then check if your hash is valid.
Still, I encourage you to use password_hash() and password_verify().
The answer to this question is "don't". Storing passwords as MD5 hashes is dangerously insecure, and should not be done. Same thing with SHA1 hashes.
PHP has built-in password_hash and password_verify functions since PHP 5.5. These should be used whenever you need to store a password.

PHP: How to retrieve original value from hashed / encrypted email address [duplicate]

I need to decrypt a password. The password is encrypted with password_hash function.
$password = 'examplepassword';
$crypted = password_hash($password, PASSWORD_DEFAULT);
Now, let's assume that $crypted is stored in a database (there's a "users" table, with usernames, passwords, etc) and I need to do a login: I have to see if the password entered by the user matches the encrypted password stored in the database.
This is the sql code...
$sql_script = 'select * from USERS where username="'.$username.'" and password="'.$inputpassword.'"';
...but $inputpassword is not encrypted, so it's not equal to what is stored in the password field of the table users...
So, there's a function to decrypt after the use of password_hash? Or should I change my encrypt method? Or what else?
Bcrypt is a one-way hashing algorithm, you can't decrypt hashes. Use password_verify to check whether a password matches the stored hash:
<?php
// See the password_hash() example to see where this came from.
$hash = '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq';
if (password_verify('rasmuslerdorf', $hash)) {
echo 'Password is valid!';
} else {
echo 'Invalid password.';
}
In your case, run the SQL query using only the username:
$sql_script = 'SELECT * FROM USERS WHERE username=?';
And do the password validation in PHP using a code that is similar to the example above.
The way you are constructing the query is very dangerous. If you don't parameterize the input properly, the code will be vulnerable to SQL injection attacks. See this Stack Overflow answer on how to prevent SQL injection.
The passwords cannot be decrypted as will makes a vulnerability for users. So, you can simply use password_verify() method to compare the passwords.
if(password_verify($upass, $userRow['user_pass'])){
//code for redirecting to login screen }
where, $upass is password entered by user and $userRow['user_pass'] is user_pass field in database which is encrypted by password_hash() function.
I need to decrypt a password. The password is crypted with
password_hash function.
$password = 'examplepassword';
$crypted = password_hash($password, PASSWORD_DEFAULT);
Its not clear to me if you need password_verify, or you are trying to gain unauthorized access to the application or database. Other have talked about password_verify, so here's how you could gain unauthorized access. Its what bad guys often do when they try to gain access to a system.
First, create a list of plain text passwords. A plain text list can be found in a number of places due to the massive data breaches from companies like Adobe. Sort the list and then take the top 10,000 or 100,000 or so.
Second, create a list of digested passwords. Simply encrypt or hash the password. Based on your code above, it does not look like a salt is being used (or its a fixed salt). This makes the attack very easy.
Third, for each digested password in the list, perform a select in an attempt to find a user who is using the password:
$sql_script = 'select * from USERS where password="'.$digested_password.'"'
Fourth, profit.
So, rather than picking a user and trying to reverse their password, the bad guy picks a common password and tries to find a user who is using it. Odds are on the bad guy's side...
Because the bad guy does these things, it would behove you to not let users choose common passwords. In this case, take a look at ProCheck, EnFilter or Hyppocrates (et al). They are filtering libraries that reject bad passwords. ProCheck achieves very high compression, and can digest multi-million word password lists into a 30KB data file.
Use the password_verify() function
if (password_vertify($inputpassword, $row['password'])) {
print "Logged in";
else {
print "Password Incorrect";
}
it seems someone finally has created a script to decrypt password_hash.
checkout this one: https://pastebin.com/Sn19ShVX
<?php
error_reporting(0);
# Coded by L0c4lh34rtz - IndoXploit
# \n -> linux
# \r\n -> windows
$list = explode("\n", file_get_contents($argv[1])); # change \n to \r\n if you're using windows
# ------------------- #
$hash = '$2y$10$BxO1iVD3HYjVO83NJ58VgeM4wNc7gd3gpggEV8OoHzB1dOCThBpb6'; # hash here, NB: use single quote (') , don't use double quote (")
if(isset($argv[1])) {
foreach($list as $wordlist) {
print " [+]"; print (password_verify($wordlist, $hash)) ? "$hash -> $wordlist (OK)\n" : "$hash -> $wordlist (SALAH)\n";
}
} else {
print "usage: php ".$argv[0]." wordlist.txt\n";
}
?>

How can I decrypt a password hash in PHP?

I need to decrypt a password. The password is encrypted with password_hash function.
$password = 'examplepassword';
$crypted = password_hash($password, PASSWORD_DEFAULT);
Now, let's assume that $crypted is stored in a database (there's a "users" table, with usernames, passwords, etc) and I need to do a login: I have to see if the password entered by the user matches the encrypted password stored in the database.
This is the sql code...
$sql_script = 'select * from USERS where username="'.$username.'" and password="'.$inputpassword.'"';
...but $inputpassword is not encrypted, so it's not equal to what is stored in the password field of the table users...
So, there's a function to decrypt after the use of password_hash? Or should I change my encrypt method? Or what else?
Bcrypt is a one-way hashing algorithm, you can't decrypt hashes. Use password_verify to check whether a password matches the stored hash:
<?php
// See the password_hash() example to see where this came from.
$hash = '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq';
if (password_verify('rasmuslerdorf', $hash)) {
echo 'Password is valid!';
} else {
echo 'Invalid password.';
}
In your case, run the SQL query using only the username:
$sql_script = 'SELECT * FROM USERS WHERE username=?';
And do the password validation in PHP using a code that is similar to the example above.
The way you are constructing the query is very dangerous. If you don't parameterize the input properly, the code will be vulnerable to SQL injection attacks. See this Stack Overflow answer on how to prevent SQL injection.
The passwords cannot be decrypted as will makes a vulnerability for users. So, you can simply use password_verify() method to compare the passwords.
if(password_verify($upass, $userRow['user_pass'])){
//code for redirecting to login screen }
where, $upass is password entered by user and $userRow['user_pass'] is user_pass field in database which is encrypted by password_hash() function.
I need to decrypt a password. The password is crypted with
password_hash function.
$password = 'examplepassword';
$crypted = password_hash($password, PASSWORD_DEFAULT);
Its not clear to me if you need password_verify, or you are trying to gain unauthorized access to the application or database. Other have talked about password_verify, so here's how you could gain unauthorized access. Its what bad guys often do when they try to gain access to a system.
First, create a list of plain text passwords. A plain text list can be found in a number of places due to the massive data breaches from companies like Adobe. Sort the list and then take the top 10,000 or 100,000 or so.
Second, create a list of digested passwords. Simply encrypt or hash the password. Based on your code above, it does not look like a salt is being used (or its a fixed salt). This makes the attack very easy.
Third, for each digested password in the list, perform a select in an attempt to find a user who is using the password:
$sql_script = 'select * from USERS where password="'.$digested_password.'"'
Fourth, profit.
So, rather than picking a user and trying to reverse their password, the bad guy picks a common password and tries to find a user who is using it. Odds are on the bad guy's side...
Because the bad guy does these things, it would behove you to not let users choose common passwords. In this case, take a look at ProCheck, EnFilter or Hyppocrates (et al). They are filtering libraries that reject bad passwords. ProCheck achieves very high compression, and can digest multi-million word password lists into a 30KB data file.
Use the password_verify() function
if (password_vertify($inputpassword, $row['password'])) {
print "Logged in";
else {
print "Password Incorrect";
}
it seems someone finally has created a script to decrypt password_hash.
checkout this one: https://pastebin.com/Sn19ShVX
<?php
error_reporting(0);
# Coded by L0c4lh34rtz - IndoXploit
# \n -> linux
# \r\n -> windows
$list = explode("\n", file_get_contents($argv[1])); # change \n to \r\n if you're using windows
# ------------------- #
$hash = '$2y$10$BxO1iVD3HYjVO83NJ58VgeM4wNc7gd3gpggEV8OoHzB1dOCThBpb6'; # hash here, NB: use single quote (') , don't use double quote (")
if(isset($argv[1])) {
foreach($list as $wordlist) {
print " [+]"; print (password_verify($wordlist, $hash)) ? "$hash -> $wordlist (OK)\n" : "$hash -> $wordlist (SALAH)\n";
}
} else {
print "usage: php ".$argv[0]." wordlist.txt\n";
}
?>

How do I create and store md5 passwords in mysql

Probably a very newbie question but, Ive been reading around and have found some difficulty in understanding the creation and storage of passwords. From what i've read md5/hash passwords are the best ways to store them in a database. However, how would I go about creating those passwords in the first place?
So say I have a login page with user bob, and password bob123
- how will I
1. get bobs password into the database to begin with (hashed)
2. how do I retrive and confirm the hashed password?
Thanks
Edit 2017/11/09: Be sure to take a look at the answer from O Jones.
First off MD5 isn't the greatest hashing method you could use for this try sha256 or sha512
That said lets use hash('sha256') instead of md5() to represent the hashing part of the process.
When you first create a username and password you will hash the raw password with some salt (some random extra characters added to each password to make them longer/stronger).
Might look something like this coming in from the create user form:
$escapedName = mysql_real_escape_string($_POST['name']); # use whatever escaping function your db requires this is very important.
$escapedPW = mysql_real_escape_string($_POST['password']);
# generate a random salt to use for this account
$salt = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM));
$saltedPW = $escapedPW . $salt;
$hashedPW = hash('sha256', $saltedPW);
$query = "insert into user (name, password, salt) values ('$escapedName', '$hashedPW', '$salt'); ";
Then on login it'll look something like this:
$escapedName = mysql_real_escape_string($_POST['name']);
$escapedPW = mysql_real_escape_string($_POST['password']);
$saltQuery = "select salt from user where name = '$escapedName';";
$result = mysql_query($saltQuery);
# you'll want some error handling in production code :)
# see http://php.net/manual/en/function.mysql-query.php Example #2 for the general error handling template
$row = mysql_fetch_assoc($result);
$salt = $row['salt'];
$saltedPW = $escapedPW . $salt;
$hashedPW = hash('sha256', $saltedPW);
$query = "select * from user where name = '$escapedName' and password = '$hashedPW'; ";
# if nonzero query return then successful login
you have to reason in terms of hased password:
store the password as md5('bob123'); when bob is register to your app
$query = "INSERT INTO users (username,password) VALUES('bob','".md5('bob123')."');
then, when bob is logging-in:
$query = "SELECT * FROM users WHERE username = 'bob' AND password = '".md5('bob123')."';
obvioulsy use variables for username and password, these queries are generated by php and then you can execute them on mysql
Please don't use MD5 for password hashing. Such passwords can be cracked in milliseconds. You're sure to be pwned by cybercriminals.
PHP offers a high-quality and future proof password hashing subsystem based on a reliable random salt and multiple rounds of Rijndael / AES encryption.
When a user first provides a password you can hash it like this:
$pass = 'whatever the user typed in';
$hashed_password = password_hash( "secret pass phrase", PASSWORD_DEFAULT );
Then, store $hashed_password in a varchar(255) column in MySQL. Later, when the user wants to log in, you can retrieve the hashed password from MySQL and compare it to the password the user offered to log in.
$pass = 'whatever the user typed in';
$hashed_password = 'what you retrieved from MySQL for this user';
if ( password_verify ( $pass , $hashed_password )) {
/* future proof the password */
if ( password_needs_rehash($hashed_password , PASSWORD_DEFAULT)) {
/* recreate the hash */
$rehashed_password = password_hash($pass, PASSWORD_DEFAULT );
/* store the rehashed password in MySQL */
}
/* password verified, let the user in */
}
else {
/* password not verified, tell the intruder to get lost */
}
How does this future-proofing work? Future releases of PHP will adapt to match faster and easier to crack encryption. If it's necessary to rehash passwords to make them harder to crack, the future implementation of the password_needs_rehash() function will detect that.
Don't reinvent the flat tire. Use professionally designed and vetted open source code for security.
Insertion:
INSERT INTO ... VALUES ('bob', MD5('bobspassword'));
retrieval:
SELECT ... FROM ... WHERE ... AND password=md5('hopefullybobspassword');
is how'd you'd do it directly in the queries. However, if your MySQL has query logging enabled, then the passwords' plaintext will get written out to this log. So... you'd want to do the MD5 conversion in your script, and then insert that resulting hash into the query.
PHP has a method called md5 ;-) Just $password = md5($passToEncrypt);
If you are searching in a SQL u can use a MySQL Method MD5() too....
SELECT * FROM user WHERE Password='. md5($password) .'
or
SELECT * FROM ser WHERE Password=MD5('. $password .')
To insert it u can do it the same way.
Why don't you use the MySQL built in password hasher:
http://dev.mysql.com/doc/refman/5.1/en/password-hashing.html
mysql> SELECT PASSWORD('mypass');
+-------------------------------------------+
| PASSWORD('mypass') |
+-------------------------------------------+
| *6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4 |
+-------------------------------------------+
for comparison you could something like this:
select id from PassworTable where Userid='<userid>' and Password=PASSWORD('<password>')
and if it returns a value then the user is correct.
I'm not amazing at PHP, but I think this is what you do:
$password = md5($password)
and $password would be the $_POST['password'] or whatever
just get the hash by following line and store it into the database:
$encryptedValue = md5("YOUR STRING");
To increase security even more, You can have md5 encryption along with two different salt strings, one static salt defined in php file and then one more randomly generated unique salt for each password record.
Here is how you can generate salt, md5 string and store:
$unique_salt_string = hash('md5', microtime());
$password = hash('md5', $_POST['password'].'static_salt'.$unique_salt_string);
$query = "INSERT INTO users (username,password,salt) VALUES('bob','".$password."', '".$unique_salt_string."');
Now you have a static salt, which is valid for all your passwords, that is stored in the .php file. Then, at registration execution, you generate a unique hash for that specific password.
This all ends up with: two passwords that are spelled exactly the same, will have two different hashes. The unique hash is stored in the database along with the current id. If someone grab the database, they will have every single unique salt for every specific password. But what they don't have is your static salt, which make things a lot harder for every "hacker" out there.
This is how you check the validity of your password on login.php for example:
$user = //username input;
$db_query = mysql_query("SELECT salt FROM users WHERE username='$user'");
while($salt = mysql_fetch_array($db_query)) {
$password = hash('md5',$_POST['userpassword'].'static_salt'.$salt[salt]);
}
This method is very powerful and secure. If you want to use sha512 encryption, just to put that inside the hash function instead of md5 in above code.

PHP AJAX login, is this method secure?

I have just started PHP and mySQL and need to know if this is "safe". The login information is passed into the following PHP file through AJAX (jQuery).
jQuery AJAX
$("#login_form").submit(function(){
$.post("login.php",{user:$('#username').val(),pass:$('#password').val()} ,function(data)
PHP
ob_start();
mysql_connect("-", "-", "-") or die("ERROR. Could not connect to Database.");
mysql_select_db("-")or die("ERROR. Could not select Database.");
//Get Username and Password, md5 the password then protect from injection.
$pass = md5($pass);
$user = stripslashes($user);
$pass = stripslashes($pass);
$user = mysql_real_escape_string($user);
$pass = mysql_real_escape_string($pass);
//See if the Username exists.
$user_result=mysql_query("SELECT * FROM users WHERE username='$user'");
$user_count=mysql_num_rows($user_result);
if($user_count==1){
if($pass_length==0){ echo "userVALID"; }
else{
$pass_result=mysql_query("SELECT * FROM users WHERE username='$user' and password='$pass'");
$pass_count=mysql_num_rows($pass_result);
if($pass_count==1){
session_register("user");
session_register("pass");
echo "passVALID";
}
else { echo "passERROR"; }
}
}
else { echo "userERROR"; }
ob_end_flush();
I know this may not be the best way to do things but, it is the way I know! I just want to know if it has any major security flaws. It is more of a concept for me and therefore I am not incorporating SSL.
You should make this change just in case people have a backslash in their password:
if(get_magic_quotes_gpc()){
$user = stripslashes($user);
$pass = stripslashes($pass);
}
$user = mysql_real_escape_string($user);
$pass = sha256($salt.$pass);
First and foremost md5 is very bad. Also md5() and mysql_real_escape_string() is redundant. Collisions have been generated in the wild. sha1() although weakened is still much more secure and no collisions have been generated (yet). The best choice would be sha256 in php, or using the mhash library.
$pass = md5($pass);
You also need to salt the password.
It suffers from
Sending the password over an unencrypted connection (use HTTPS at least to send the username and password; this protects the password against passive attackers but not against active ones. To be secure against active attackers, you must encrypt all the communications).
Storing the password in the database (you should store a salted hash instead).
Also never tell user things like "user doesn't exist" or "incorrect password". It's much better if you just print out "Incorrect username or password" so everyone cannot check for existing usernames and then try to guess password for these.
session_register() is deprecated, you should be using $_SESSION[].
You're also performing your string escapes on a hashed password string $pass; it will always have a hex value and so doesn't need to be escaped. You can perform escapes on the password string before the hash, but that's only marginally useful (e.g., if you allowed passphrases to be saved by users that included characters that needed to be escaped. Generally I disallow this on the registration side of the code). You should also use a salt.
Base on my research:
using jquery ajax to login is as safe as plain old form. data is always sent through http request. reference: ajax safe for login?
use SSL (https) in login form gives extra security.
instead of using mysql_connect, you should use prepared statements
reference: why prepared statement? and prepared statement usage example
you should use one-way password hashing algorithm, such as Bcrypt. one-way hashing algorithm means you cannot convert hashed password back to plain text. but you can verify the keyed in password against the hashed password stored in database. reference: don't encrypt password, hash it instead. and the Bcrypt and how to use it

Categories