This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do you use bcrypt for hashing passwords in PHP?
What is the secure way or hash function to store password to Mysql Database? Now I'm using this sha1() function to store my password to DB with following code. Is it really Safe?
<?php
$pass = 123456789;
$pass = sha1($pass);
echo $pass;
?>
Thanks for your advise.
Update
I see salt is something like this.
$salt = "this is a salt";
$password = 'this is an password';
$hash = sha1($salt.$password);
So, Can i use any number/random number/something to $salt value? After that is it Now SAFE?
The SHA* variants should not be used for password hashing. Use the Blowfish algorithm and the crypt() function.
phpass is a PHP password hashing library that can simplify this for you.
You could also do more research on the topic and write some code to generate your own Bcrypt/Blowfish compatible Salts and use crypt() directly, rather than using the phpass library.
The best (and recommended) way of hashing passwords in PHP is using crypt().
Here's a simple example from the PHP documentation:
$hashed_password = crypt('mypassword');
// now store $hashed_password in the database
Later, to check an entered password (assuming $user_input is the entered password):
// retrieve $hashed_password from the database, then:
if (crypt($user_input, $hashed_password) == $hashed_password) {
echo "Password verified!";
}
Note that in this example (above) the salt is automatically generated when the password is first hashed. This is dangerous and should be avoided. A pseudo-random salt should be provided and could be generated like so:
$salt = substr(str_replace('+', '.', base64_encode(pack('N4', mt_rand(), mt_rand(), mt_rand(), mt_rand()))), 0, 22);
For a much better explanation, see the Stack Overflow question linked by citricsquid.
You cannot use a random value for salt, since you wont be able to compare the inputed password and the one stored in database afterwards.
You encryption is mainly ok, but you can go real crazy if you want...
<?php
$salt = "fF#$GGG$T##4309g9jERGWrgrew#GH";
$pepper = "vV###V90Ù39009gfjigwjorn)(";
$pass = "123456789";
$pass = $salt.$pass.$pepper;
for ($i=0;$i<40;$i++){
$pass = hash("sha256", $pass)
}
echo $pass;
?>
Related
This question already has answers here:
Using PHP 5.5's password_hash and password_verify function
(4 answers)
Closed 7 years ago.
I am thinking of using password_hash() function to encrypt user passwords. I understand that this function generates salt by default if you don't provide it, and it is even encouraged to use the default salt instead of your own. I am currently weighing in 3 options and can't decide which one to go with so I'd appreciate it if you could help me out.
1. option: password_hash() with default salt
$passwordInput = $_POST['password'];
$passwordHash = password_hash($passwordInput, PASSWORD_BCRYPT);
//INSERT $passwordHash INTO DATABASE
2. option: password_hash() with custom salt
$options = ['salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM)];
$passwordInput = $_POST['password'];
$passwordHash = password_hash($passwordInput, PASSWORD_BCRYPT, $options);
//INSERT $passwordHash INTO DATABASE
3. option: not using password_hash() at all
I am basing this option on a post from 2014: The definitive guide to form-based website authentication. Basically if it is a more secure approach than password_hash() I'd use something like this:
$salt = uniqid(rand(0, 1000000);
$passwordInput = $_POST['password'];
$password = hash('sha512', $salt . $passwordInput);
//INSERT $password AND $salt INTO DATABASE SEPARATELY
The really short answer to this question is to use password_hash() with the default salt (your first option), custom salt is deprecated in PHP7 because, to quote php.net:
The salt option for the password_hash() function has been deprecated to prevent developers from generating their own (usually insecure) salts. The function itself generates a cryptographically secure salt when no salt is provided by the developer - therefore custom salt generation should not be needed.
By the same token, your third option, hash() should be avoided as again you'll need to generate your own salt.
This question already has answers here:
Secure hash and salt for PHP passwords
(14 answers)
Closed 7 years ago.
I have been reading a lot online that MD5 is not very secure, i have decided to switch my site over to use SHA512, i have never done this before so really i am just asking you to check to see if i have done it correctly, or is there an alternative more secure hash method which i can use to store the password ?
$upass is the users password which i need to hash.
Here was my origional PHP with MD5 :
$uname = mysql_real_escape_string($_POST['uname']);
$sname = mysql_real_escape_string($_POST['sname']);
$email = mysql_real_escape_string($_POST['email']);
$upass = md5(mysql_real_escape_string($_POST['pass']));
Here is my new PHP using SHA :
$uname = mysql_real_escape_string($_POST['uname']);
$sname = mysql_real_escape_string($_POST['sname']);
$email = mysql_real_escape_string($_POST['email']);
$upass = mysql_real_escape_string($_POST['pass']);
$upass = hash('SHA512', $upass);
Here is also the hashed string for the word "password" just to make sure the hashing is working.
SHA512 :
b109f3bbbc244eb82441917ed06d618b9008dd09b3befd1b5e
MD5 :
5f4dcc3b5aa765d61d8327deb882cf99
Thanks for any help / advice in advance.
The right way would be to use password_hash using PASSWORD_DEFAULT for the algorithm. That way, you will have a good algorithm (bcrypt, if you have PHP 5.5), which may be automatically upgraded to a better one in future versions of PHP, withouth the need to change your code. The passwords are also hashed with a salt.
This question already has an answer here:
How to check a mysql encrypt value with a salt in PHP?
(1 answer)
Closed 9 years ago.
I would like to encrypt some passwords and put it in database. How do I keep this stuff in a database so I can retrieve the data if the owner matches.
Example
<?php
// some validations and other staff
$data = $_POST['input'];
$hash = crypt($data);
//then database insert code
?>
If I echo the $hash, it's giving me some encrypted data but when I refresh the page, the numbers are changing from time to time. How do I keep the data static? How will I tell the encrypted password that this was the owner when username and password entered.
Example
<?php
//time of encryption
$name = "someone";
$pass = "p1x6Fui0p>j";
$hash = "$pass"; //outcome of $hash e.g. $1$aD2.bo0.$S93XNfgOFLskhis0qjE.Q/
// $hash and $name inserted in database
?>
When the user tries to login with collect details, how will I refer $hash "$1$aD2.bo0.$S93XNfgOFLskhis0qjE.Q/" was equal to $pass "p1x6Fui0p>j" ?
crypt() has an unfortunate name. It's not an encryption function, but a one-way hashing function.
If you're using PHP 5.5+, just use password_hash and password_verify:
$hash = password_hash($data, PASSWORD_BCRYPT); // Bcrypt is slow, which is good
And to verify the entered password:
if (password_verify($pass, $hash)) {
// The password is correct
}
Now to answer your actual question: the purpose of password hashing is to authenticate users without actually storing their plaintext passwords. If hash(a) == hash(b), then you can be pretty sure that a == b. In your case, you already have hash(a) ($hash), so you just need to hash the inputted password and compare the resulting hashes.
crypt() does this for you:
if (crypt($pass, $hash) === $hash) {
// The password is correct
}
From the php crypt page
if (crypt($user_input, $hashed_password) == $hashed_password) {
echo "Password verified!";
}
You are not using your own salt, so for every call salt is automatically generated, and salted password is hashed. To get the same hash from this password, you need to run crypt with exact salt that was generated during first run.
Generated salt varies depending on algorithm used for hashing, but from your example it's MD5, and salt is delimited by first and third dollar sign inclusively:
$hash = '$1$aD2.bo0.$S93XNfgOFLskhis0qjE.Q/';
// \ salt /
So to get Exact same hash you need to call crypt($pass, '$1$aD2.bo0.$');
Remember that if you want to use your own salt, it needs to be in proper format for given algorithm. For best results use php 5.5+ password_hash mentioned by #Blender, and for older php versions there is password_compat library, with this you don't have to worry about proper salt format.
This question already has answers here:
Secure hash and salt for PHP passwords
(14 answers)
Closed 9 years ago.
I have found an article with the code below on the web I want to use to learn more php/mysql...
$username = 'Admin';
$password = 'gf45_gdf#4hg';
$salt = hash('sha256', uniqid(mt_rand(), true) . 'a random string will go here' . strtolower($username));
$hash = $salt . $password;
for ( $i = 0; $i < 100000; $i ++ ) {
$hash = hash('sha256', $hash); }
$hash = $salt . $hash;
How would I validate the password in PHP when a user wants to log in?
You would run the exact same procedure and see if the results match.
This is a general procedure for seeing if a sumbitted password stores a matched password.
You create a function which hashes and stores the known password, and typically salts it as well
You store that in the database
When the user submits a password to login, you run it through the exact same hashing and salting algorithm, and see if the resulting hash matches the hash stored in the database
You should also consider using bcrypt instead: How do you use bcrypt for hashing passwords in PHP?
It's recommended to compose a function within PHP that similarly mimics the process you've outlined above. That way, when you're attempting to validate submitted credentials, you will run the password through the same hashing process as it was during conception with the exception of generating the random salt.
Before I start I'd like to apologise for bringing up this subject once again, as many users did, but with a research I did, I wasn't happy with what I've found. I just hope to come up with something really helpful here.
Since md5 or sha1 are considered bad practice (even when using salts ???), I have tried to create this function for hashing my password
$password = $_POST['password']; // lets say that my password is: my_sercretp#ssword123
function encrypt_the_password($password){
$salt = "lorem_ipsumd0l0rs1t#m3tc0ns3ct3tur#d1p1sc1ng3lit";
return hash('sha256', $salt.$password);// can use also different algorithm like sha512 or whirlpool
}
$hashed_password = encrypt_the_password($password);
Note that this one I use it in a personal website with only one user, me. In case of having more than one users I come up with something like this:
$password = $_POST['password'];
function generate_salt() {
$salt = uniqid(md5("lorem_ipsumd0l0rs1t#m3tc0ns3ct3tur#d1p1sc1ng3lit".microtime()));
$salt = hash('sha256', $salt);// can use also different algorithm like sha512 or whirlpool
return $salt;
}
function encrypt_the_password($password,$salt){
return hash('sha256', $salt.$password);// can use also different algorithm like sha512 or whirlpool
}
$hashed_password = encrypt_the_password($password,generate_salt());
Is this secure enough (in each case) or can this improved more???
MY EDIT: I tried to come up with something new using the crypt() function. Here's my code in case of having a site with only one user, admin:
$password = $_POST['password'];
$salt = "L0r3mIpsUmD0l0rS1tAm3t";
$hashed_password = crypt($password', '$2a$12$' . $salt);
and in case of having a site with more than one users:
$password = $_POST['password'];
function generate_salt() {
$salt = uniqid(sha1("L0r3mIpsUmD0l0rS1tAm3tc0ns3CT3tur4d1p1sc1ng3lit".microtime()));
$salt = substr(sha1($salt), 0, 22);
return $salt;
}
$hashed_password = crypt($password', '$2a$12$' . generate_salt());
Is this ok or needs improvements???
Improve it by not making up your own algorithm. Your algorithm is insecure because your salt is constant and you only hash with one iteration of SHA256, which is computationally cheap.
Instead, use Bcrypt, which is both computationally expensive and verified by people who know what they're doing, so it's much safer than your solution.
You should use the password functions that will come inbuilt in PHP 5.5. There's a fallback library by ircmaxell that can provide the functions in earlier versions of PHP: https://github.com/ircmaxell/password_compat
It will always use the most recent hashing technique available, and in case even update the records for you. Make sure you read the README coming along with this library.
Do not make your own hashing function.