So I'm running one project created with Laravel 5.1 and one guy said to me that passwords are not secure something like hashes don't used etc. But I can clearly see in this function that passwords are bcrypted:
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
}
And passwords also stored in DB as bcrypted. Should I be worried about his words?
Default Laravel Auth requires passwords to be bcrypted, as you've shown in your code. bcrypt is an industry standard one-way password hash and is very good.
If you roll your own authentication, we can't control how you handle your password hashing. But default Laravel Auth is secure.
If you are not using Laravel's inbuilt Authentication, use Laravel's Hash class. Hash::make('$data['password']'). But in your case, it looks solid and you don't have to worry about hashing again.
You can read https://laravel.com/docs/5.1/installation#configuration about the Application Key.
Because of bcrypt , you can only decrypt a password where it was encrypted.
I am not saying that it is perfectly safe, but even if someone knows how bcrypt works, if they don't know the encryption key, they will have a hard time decrypting it.
So make sure to php artisan key:generate , if you are not using .env configuration file.
Related
I created user and I gave him password 'secret'.
The hash that was generated by the registration process is
$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm
I wanted to generate it in the code so I used Hash::make('secret') and I got:
$2y$10$Hnbg7DCp2VObns4cbr580uo9VTYgzJF2BSNSpA7S8BYjkAgfUlH.G
finally I used bcrypt('secret') and I got:
$2y$10$5g1bhkHB7kRk8SkM3yS/YOifsEesjZ31YeYnRlE.bxSBmZutVCuui
These are all different hashes, How can I generate one that would let me change password inside my code?
It's because bcrypt doesn't work as SHA-256, it uses a key that would change the result of the hash itself for the same string.
In Laravel, you can use Hash::check('plain-text', $hashedPassword) to check the password, but you will never have the same result for the same password. check here
You can use bcrypt(secret") and leave it at laravel and test it (everything is working).
It works as intended, bcrypt doesnt always generate the same hash. Laravels Hash::check() function will return true for any valid hash of the given password.
For mor informations, look here: https://stackoverflow.com/a/8468936/6622577
Bycrypt is a more secure password hashing algorithm. Unlike md5() or SHA1() bycrypt does not always generate the same hashed value for a specific string.
So when you are storing the hashed password in the database you will use
$password = bcrypt($input['password']);
Afterwards, when you wish to check at the time of login you simply set the plain-text password (As you might be getting it from user input) and run a function called Auth::attempt() to match the password.
$userdata = array(
'username' => $input['username'],
'password' => $input['password'],
);
if (Auth::attempt($userdata)) {
// Password matched
}
And if you want to explicitly check the plain-text password corresponding to its hash then use Hash::check() as below:
Hash::check('plain-text-password', 'hashed-password);
I've struggled with a problem for a while now. I want to use Laravel for my website BUT I can only use SHA256 as the password encryption because of some other limitations in our project.
Basicly my problem consists of a function within Laravel that is used to check if the userdata is correct (Checks if the user can login) does not work for me because of my difference in encryption (Atleast that's my theory)
Auth::attempt(['username' => $username, 'password' => $password]
This function always returns false, no matter if the password is correct and I assume it's because of the difference in encryption.
Anybody know if there's a fix for this?
Auth::attempt(['username' => $username, 'password' => SHA256($password)]);
Here SHA256($password) you can call the function as the same which used for encryption and check it.
In this case, SHA256 (dummy function) will hash the password you passed and match the value.
EDIT 1
Sample Code for registration
$users = User::create([
'name' => $name,
'email' => $email,
....
....
'password' => SHA256($password)
]);
//to login with the above creds
Auth::login($users);
Now while login you can use the same SHA256 function to encrypt the input password and check with your database.
I fixed this issue with the help of the above comments from Arun Code and Andrew.
For anyone else with this issue I suggest reading this
I'm wondering how to use Hash::needsRehash() as I'm struggling to see using the documentation exactly what it's for.
if (Hash::needsRehash($hashed)) {
$hashed = Hash::make('plain-text');
}
What exactly causes Hash::needsRehash() to return true or false, does it return true if the hashed password is in another hash (such as MD5, SHA1 etc)?
In the case that your database is full of hashes in another algorithm and Hash::needsRehash() returns true, how would you rehash the users password so that it's they're up to date? You can't rely on the "login" password because it needs to be compared first to validate, right?
I guess maybe I'm overthinking things but I'm confused right now. Luckily my users passwords are using password_hash() anyway so shouldn't be a problem.
Hash::needsReHash() just calls php's built-in password_needs_rehash function. A helpful comment in the docs is:
// Check if a newer hashing algorithm is available
// or the cost has changed
if (password_needs_rehash($hash, PASSWORD_DEFAULT, $options)) {
So Hash::needsReHash() will return false if and only if hashing algorithm has changed (since you're not passing any options such as cost).
As for how and when to use this, you can only rehash a user's password when you have it -- e.g. when they're logging in. So during the login process, you check if their stored password's algorithm differs from your current algorithm, and if so, you replace their stored password hash with a new one.
This seems to be how to do it in Laravel 5.6
Put this in your LoginController:
protected function authenticated(Request $request, $user) {
if (Hash::needsRehash($user->password)) {
$user->password = Hash::make($request->password);
$user->save();
}
}
https://laravel.com/docs/5.6/hashing#basic-usage
The method returns true when PHP is updated and a new/better default algorithm was added or any other parameters changed. This lets you automatically take advantage of it without updating your code.
This method is used when a user is logging in as that is the only time you have access to the plain-text password. After confirming it is correct according to the old hash, you take the plain text password, rehash it, and put it back into the database for future use.
For a hypothetical example, lets say that right now the algorithm is md5() 10k times. In PHP7, it was updated to sha512() 15k times. If the hash is in the $count|$algo|$hash format, the method can tell when a hash is outdated. Since the old algorithm was not removed, you can still validate the password with old parameters before rehashing.
Note: obviously using md5()/sha512() is a bad idea. I'm just using them as examples.
I'm just starting out with Laravel 5, I come from Laravel 4 environment so it shouldn't be too hard.
I heard L5 comes with a built-in authentication system which is neat.
I've set everything up from database to views.
The registration process is working correctly and after that it logs me in automatically. but when I log out and try to log back in, I get this error:
These credentials do not match our records.
I'm not sure what's wrong. do I have to write the login controller manually or how does it work in L5?
I had the same issue. The reason for mine was that
I defined setPasswordAttribute in my User model so every time, I enter plain password, it hashes before sending to DB.
public function setPasswordAttribute($password)
{
$this->attributes['password'] = \Hash::make($password);
}
and in my db:seed, I was creating a user with hashed password with Hash::make("password"), too. So laravel hashes hashed password :)
In laravel version 5.* you don't need to hash input password for Auth, because Auth manages it itself. you just have to pass {{csrf_field()}} through form.
In addition to #mervasdayi solution, a good way to hash passwords in setPasswordAttribute avoiding rehashing problems could be this:
public function setPasswordAttribute($password){
$this->attributes['password'] = Hash::needsRehash($password) ? Hash::make($password) : $password;
}
Further to what #mervasdayi & Gerard Reches have suggested. Just thought I'd make a note that you will need to include
use Illuminate\Support\Facades\Hash;
at the top of your User model when adding in these fixes.
I think that it is later but i found two solutions to solve this problem.
Firstly you can use bcrypt function if you use laravel 5.3. Look at the below function. It means that your get your data in array.
public function create(array $data)
{
return User::create([
'password' => bcrypt($data['password']),
]);
}
Secondly you can use mutator to fix it like this:
public function setPasswordAttribute($password)
{
$this->attributes['password'] = \Hash::make($password);
}
Hope that it can help others. Best regards
In my case, I attempt too many times with the wrong password, and then I am unable to login with the user for some hour, and at the same time, I am able to log in with other users.
I'm trying to implement authentication in laravel 4
When the user registers, I hash the password and save it, like this:
$password = Hash::make(Input::get('password'));
Then when the user tries to login, I want to authenticate him/her with the following code:
if (Auth::attempt(array('username' => Input::get('username'), 'password' => Hash::make(Input::get('password')))))
{
return Redirect::intended('dashboard');
}
and that never succeeds. I tried to debug the code and it seems that the Hash::make function always gives a different result.
Am I using a good authentication methods?
Don't Hash the password you are giving to the Auth::attempt method, it should be like this:
Auth::attempt(array('username' => Input::get('username'), 'password' => Input::get('password')));
You may also check the password using Hash::check('password', $hashedPassword). Read more about security on Laravel website.
Do not hash the password in the auth::attempt() function the code should be like this:
Auth::attempt(array('username' => Input::get('username'), 'password' => Input::get('password')));
The auth::attempt() will hash the password and then check if it matches the one stored in the database
To add some explanation to the answer, it is different every time because the hashing algorithm bcrypt generates a random string (salt) that has to be used to decrypt the password.
This is to protect passwords from rainbow table attacks. https://en.wikipedia.org/wiki/Rainbow_table