This question already has answers here:
How to reverse SHA1 Encrypted text [duplicate]
(3 answers)
Closed 9 years ago.
I don't think that my title is appropriate for my question.
My question is I have a simle login system just for test purposes, and I am using sha1 in encrypting my password into my database. which would look like this
sha1($_POST['..some_variable...'])
What would be the best way to retrieve my encrypted password as plain text for authentication purposes.
Like select my username and password from my database.
This should give you a good idea of how it works.
try {
$submittedEmail = !empty($_GET['email']) ? $_GET['email']: false;
$submittedHash = !empty($_GET['password']) ? hash('sha1', $_GET['password']): false;
if (!$submittedEmail || !$submittedHash) {
throw new \Exception('Required field(s) missing. Please try again.');
}
if ($stmt = $mysqli->prepare("SELECT hash FROM user WHERE email = ?")) {
$stmt->bind_param("s", $submittedEmail);
$stmt->execute();
$stmt->bind_result($storedHash);
$stmt->fetch();
$stmt->close();
}
if (!$submittedHash != $storedHash) {
throw new \Exception('Wrong credentials submitted. Please try again.');
}
echo 'User ok!';
} catch (Exception $e) {
echo $e->getMessage();
}
I would however recommend using PHPs password_verify
Since you probably aren't on PHP 5.5 yet you can use this class
When the user creates an account and/or password the first thing you need to do is create a random salt.
$salt = hash_hmac('sha512', "RandomStringHere", "EncryptionKeyHere");
You will store that salt in db along with their encrypted password. From there encrypt the text-based password to and store it in the db.
$encyptPassword = hash_hmac('sha512', "plainTextPassword" . $salt , "EncryptionKeyHere");
So now you have a salt and encrypted password associated with the user.
To authenticate it's as easy as getting the salt associated with the user, taking their un-encrypted password and encrypting it - seeing if it matches.
This way you never know the persons password, just if it matches when they try to log in.
Related
This question already has answers here:
How to verify_password from a database
(2 answers)
Closed 3 years ago.
So I have a login page which worked fine without hashed passwords but of course, that wasn't secure so I decided to hash the passwords when registering.
but I don't know how and where should I use verify_password when I'm selecting the password from the database. I use while to see if there is a result with the username and password entered like this:
$q = "SELECT * FROM users WHERE username='$username' AND password='$password'";
$x = $conn->query($q);
if ($x->num_rows > 0) {
while ($row = $x->fetch_assoc()) {
//Logged in seccesfully!
}
} else {
// Username or password is wrong!
}
password_hash() function can simplify our lives and our code can be secure. When you need to hash a password, just feed it to the function and it will return the hash which you can store in your database.
$hash = password_hash($password, PASSWORD_DEFAULT);
Now that you have seen how to generate hashes with the new API, let’s see how to verify a password. Remember that you store the hashes in a database, but it’s the plain password that you get when a user logs in.
The password_verify() function takes a plain password and the hashed string as its two arguments. It returns true if the hash matches the specified password.
<?php
if (password_verify($password, $hash)) {
// Success!
}
else {
// Invalid credentials
}
for more info read
I am using sha1 for my password security. I have stored password in this way in register.php
// secure password
$salt = openssl_random_pseudo_bytes(20);
$secured_password = sha1($password . $salt);
//Send it to mysql table
$result = $access->registerUser($username, $secured_password, $salt, $email, $fullname);
This all is working fine.
Problem is here:
In my login.php
$password = htmlentities($_POST["password"]);
$secure_password = $user["password"];
$salt = $user["salt"];
// 4.2 Check if entered passwords match with password from database
if ($secure_password == sha1($password . $salt)) {
//do something
} else {
//do something
}
I am always getting as password does not match.
where am I going wrong?
First is first. NEVER USE SHA OR MCRYPT TO STORE YOUR PASSWORD.
EDIT : The password_hash() function generates a long password hash, so make sure that your column in the mysql is a VARCHAR of 500 space
All these useless practises is the root reason why almost many websites get hacked. To tackle the situation, php did a lot of research and then at last came with the most secure function called the password_hash(). I am not more onto explaining about password_hash() here as there are already many documents on the internet.
You can always hash a password like this
<?php
$securePassword = password_hash($_POST['password'], PASSWORD_DEFAULT);
$query = $db->query('INSERT INTO users ......');
?>
And, to verify the password, you can simply use this function
<?php
$passwordHash = $query['password']; //Password from database
$userPassword = $_POST['password']; //Password from form
if(password_verify($userPassword, $passwordHash)) {
echo 'Password is correct, logged in!';
} else {
echo 'Password is wrong, try again';
}
?>
And, answer for your question.
PLEASE DON'T USE SHA OR MCRYPT OR BCRYPT. IF YOU WANNA GET YOUR WEBSITE HACKED, THEN CONTINUE. OR USE password_hash()
The reason you don't get the hash genereated each time because the openssl_random_pseudo_bytes() generates random numbers each time. So each time, during execution, the function returns different numbers and you get your sha result wrong and thus giving a FALSE alert.
PLEASE, AGAIN. I BEG YOU TO USE password_hash() FUNCTION
For more information on password_hash() and password_verify() :
http://php.net/manual/en/function.password-hash.php
http://php.net/manual/en/function.password-verify.php
im doing a tutorial about how to make a php mysql login form.
now the tutorial is actualy made to good and i wold like to alter it a bit and change the login password to store cleartext instead of the hash. the hash line looks like this:
$new_password = password_hash($upass, PASSWORD_DEFAULT);
i made:
$new_password = $upass;
out of it. and it now saves the cleartext to the database but the login doesn't work.
the login part looks like this and i don't see the part where i expect the hashed-password to be converted and matched...
public function doLogin($uname,$upass)
{
try
{
$stmt = $this->conn->prepare("SELECT user_id, user_name, user_pass FROM users WHERE user_name=:uname");
$stmt->execute(array(':uname'=>$uname));
$userRow=$stmt->fetch(PDO::FETCH_ASSOC);
if($stmt->rowCount() == 1)
{
if(password_verify($upass, $userRow['user_pass']))
{
$_SESSION['user_session'] = $userRow['user_id'];
return true;
}
else
{
return false;
}
}
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}
The line:
if(password_verify($upass, $userRow['user_pass']))
Checks the hash of the password against the given password. As you've removed the hashing function it's comparing an un-hashed password against a clear text password.
Change it to:
if($upass == $userRow['user_pass'])
That should fix it.
Although you really should not be storing clear text passwords.
If you're not hashing the passwords anymore then you can't verify the hash
if(password_verify($upass, $userRow['user_pass']))
Should be
if($upass == $userRow['user_pass'])
Understand that this is a very bad idea. You might not understand why hashing passwords is important
For any reason, your database may be compromised and its data may be obtained by someone else. If the passwords are in what we call plain text, you will have leaked a piece of sensitive information that your users have trusted you with: their password (which is very likely to be a password shared in multiple services). This is a very serious issue.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Secure hash and salt for PHP passwords
I am working on a PHP script for my site, the site it's self is up and running. The problem I have is that the registration on the website is for plain text passwords. Obviously this is very weak security. I am hoping someone can help me convert it so I can use a hash password.
I have included part of the registration code that I think counts. I did not include all code on the page as I did not think it relevant but will supply if someone thinks it will help.
require 'include.inc';
if ($signup) {
if ($signup[repassword] != $signup[password]) {
$err_msg = "Your passwords do not match.";
error($err_msg);
}
if(!preg_match("^[_\.0-9a-z-]+$/i^", $str)) {
$msg = 'Invalid Username! Usernames can consist of letters and numbers only';
}
if(!preg_match("^[_\.0-9a-z-]+$^",$signup[password])) {
$err_msg = "Invalid Password! Passwords can consist of letters and numbers only.";
}
if(!$signup[password] || !$signup[username] || !$signup[email] || !$signup[username])
$err_msg = "Oops! You forgot some important fields!";
if (!$err_msg) {
$usercheck = #mysql_query("INSERT INTO user values(
'NULL','$signup[fname]','$signup[lname]',
'$signup[username]','$signup[password]','$signup[email]', 1, ".$pointInc.", '$signup[referral]', NOW(), 'n', 'y')");
// done, you are entered correctly, Now Enter the points and URL info
$sql = "Select id from user where username='$signup[username]'";
$result = mysql_query( $sql );
if ( $result != false )
{
while ( $data = mysql_fetch_assoc( $result ) )
{
$point_set = $data['id'];
}
} else {
echo mysql_error();
}
// add rerral points
if ($signup[referral]) {
$referralSql="UPDATE points SET points=points+ ".$refPoints . " WHERE userid=".$signup[referral];
$result = mysql_query( $referralSql );
if ( $result != false )
{
} else {
echo mysql_error();
}
}
// add URL
$sql="INSERT INTO url_table ( userid, website, active, datechanged) VALUES ($point_set,'".$signup[site_url]."','n', '".date("Ymd")."')";
$result = mysql_query( $sql );
if ( $result != false )
{
} else {
echo mysql_error();
}
// add points
$sql="INSERT INTO points (userid, username, points) VALUES ($point_set,' ',$signPoints)";
$result = mysql_query( $sql );
if ( $result != false )
{
} else {
echo mysql_error();
}
}
echo mysql_errno().": ".mysql_error()."<br>";
if (!$usercheck) {
$err_msg = "Database error:<br>There was an error entering your account.<br>It is possible that username or Email already exists, please try another one.<br>";
} else {
include ("reg.php");
exit;
}
}
if (!$err_msg) {
// done, you are entered correctly
}
pageHeader($title, $bgColor, $styleSheet);
?>
The basic principle is quite easy:
1 . When a user registers, don't store the plaintext password, but hash(password).
$query = $pdoObject->prepare('INSERT INTO users (UserName, Password) VALUES (:u, :p)');
$query->bindParam(':u', $_POST['username']);
$query->bindParam(':p', hash($_POST['password']));
// Note that we don't store the password, we store the hash of the password. Once this script is done executing, no one involved in the website (except for the original user) will know that the password is
$query->execute();
2 . When a user attempts to log in, calculate the hash of the entered password with the hash stored in your user database. If both hashes match, the password is correct.
$query = $pdoObject->prepare('SELECT * FROM users WHERE UserName = :u AND Password = :p');
$query->bindParam(':u', $_POST['username']);
$query->bindParam(':p', hash($_POST['password']));
// We locate the original user by searching for the hash of the password that they typed in
So much for theory. Some practical issues you should consider:
Many tutorials suggest using MD5 of SHA1 as hash functions. However, these are not secure. Check the PHP hash library (especially the hash() function) for available hashing algorithms.
You should also consider using salted passwords. For each registered user, create a random string (the salt), concatenate this string with the user's password and then hash both password and salt (the salt needs to be saved too, because you need it again when authenticating the user).
You can use PDO to make your SQL more secure. This will protect you against something called SQL Injection. If you don't do this, then users will be able to mess up your website by entering characters such as apostrophes (').
You can use md5 function to create a hash for your passwords, example:
$password = '12345';
$password = md5($password);
You save this hash at the database and when you will check user and password for login you do this
$post['password'] = md5($post['password']);
and check if is equal of the hash saved in the database.
I know that md5 is not the best hash but is simple and has a good level of security
Use crypt for hashing passwords.
Use md5 for that http://php.net/manual/en/function.md5.php
Also look up uniqid http://php.net/manual/en/function.uniqid.php
It's always a bad practice to store the password in plain text in your database. Check this other question:
What are the best practices to encrypt passwords stored in MySql using PhP?
some opinions don't think md5 or SHA-1 breakable, try to salt them.. search that.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do you use bcrypt for hashing passwords in PHP?
I am researching the best and safest methods of encrypting and storing user passwords in a database for logins. One article I came across, Salted Password Hashing - Doing it Right, provides a fairly complicated-looking set of functions for encrypting and checking passwords.
I understand how the code works, but the article also mentions storing not only the hashed password in the database, but the salt as well. How would I go about doing that, using the given code? For example:
// User registers with username and password; assume they're already validataed
$hash = create_hash($password_entered);
$password_hash = $hash[HASH_PBKDF2_INDEX];
$salt = $hash[HASH_SALT_INDEX];
$PDO = new PDO('mysql:host=localhost;dbname=myDatabase', $username, $password);
$statement = $PDO->prepare('INSERT INTO users (username, password, user_salt)
VALUES (:username, :password; :user_salt)');
$statement->execute(array(
':username' => $username_entered,
':password' => $password_hash,
':user_salt' => $salt,
));
That seems right... however, when verifying a login, I'm not sure what to check against the entered password from the login form. The compiled hash returned by create_hash() gives a colon-delimited list of values. I'm just not sure where to go from here, or if this source code is even worth using.
I haven't used this code but I'm pretty sure you should not save user_salt separately in a column of your user table. User salt will be included in the hash (location 3 in a colon delimited hash). In your login script, get the password user has entered, and call the following function:
// here run a query and get the hashed password from the users table and put the
// hashed value in $hashed_password_from_database
// $user_enetered_password usually comes from $_POST
if (validate_password($user_entered_password, $hashed_password_from_database)) {
// login successful
} else {
// login failed
}
To verify the login, use the following function, found on the link you posted, with $password being the password entered by the user attempting to log in, and $good_hash being PBKDF2_HASH_ALGORITHM . ":" . PBKDF2_ITERATIONS . ":" . $salt_from_db . ":" . $hash_from_db
function validate_password($password, $good_hash)
{
$params = explode(":", $good_hash);
if(count($params) < HASH_SECTIONS)
return false;
$pbkdf2 = base64_decode($params[HASH_PBKDF2_INDEX]);
return slow_equals(
$pbkdf2,
pbkdf2(
$params[HASH_ALGORITHM_INDEX],
$password,
$params[HASH_SALT_INDEX],
(int)$params[HASH_ITERATION_INDEX],
strlen($pbkdf2),
true
)
);
}