Laravel 5.8 - save user emails encrypted - laravel

I'm looking for a way to encrypt the user emails in the database. Since Encrypt always generates a different string, it fails.
So I took sha1.
in AuthenticatesUsers I've changed the credentials method to:
protected function credentials(Request $request)
{
return ['email' => sha1(strtolower($request->email)), 'password' => ($request->password)];
}
This works great for the login/registration. But there are problems with resetting the password.
Resetting the password uses the SendsPasswordResetEmails trait.
There it this credentials method:
protected function credentials(Request $request)
{
return $request->only('email');
}
This always fails, cause it does not find the user (cause the user is saved with sha1 email)
if I change it to return ['email' => sha1(strtolower($request['email']))];
I get the error, that the email is not in the right RFC standart, to send a email. The Problem is, I don't really find the place, where laravel is searchig for the user with this email. Anyway, I don't really have a clue, how I can solve this problem at all.
I want to encrypt the email itself, because in germany there is a law which forces us to store personal data encrypted, like the email.

First thing to say is that Hashing is not the same as Encryption.
Encryption is a two way function, that is if you can encrypt an email you can decrypt it with a reverse function, if you know the encryption key, and obtain the original email.
Hashing is a one way function, that is if you hash a password you can't obtain the original password with a reverse function, you can only verify that, when you input the password again, the hash you obtain matches the original hash, so you only know that the two password are identical.
You usually store password hashed, not crypted, so even the administrator can't recover the original password, he con only verify that a input from a user has a hash that match the original password he entered.
You can read more in this stackoverflow question: Difference between Hashing a Password and Encrypting it.
The sha1() is a hashing function, so is not reversable, you can't obtain the original email.
Laravel has the functions encrypt() and decrypt() to encrypt things, see the docs on encryption, and has the functions Hash::make() to hash a password and Hash::check() to verify the password, see the docs on hashing.
So if you want to encrypt the emails, not hashing them with sha1, you should use encrypt() and decrypt().
The best way for you is to use mutators, i.e.:
public function getEmailAttribute($value)
{
return decrypt($value);
}
public function setEmailAttribute($value)
{
$this->attributes['email'] = encrypt($value);
}
So you will have email encrypted in the database and you can use $user->email in your code.
But I have to warn you that with encrypted email the login process is irreparably broken, you have to use another unique field like username for the login, not the email, so in your login controller you have to write:
public function username()
{
return 'username';
}

Related

how to match credential with already hashed password of user in laravel;

we know we can get a password as request and then check it with hash which determines whether user is authenticated or not. for example my password from request data is "12345678";
$user = User::select('password')->where('email', $request->email)->first();
Hash::check($request->password, $user->password);
it gives us a boolean result; but what if the password from request data is already hashed...for example "$2y$10$7slzuQpl8IKB.SOccwF8h.jQnykRyPyX66PtYgzIiYoq2u1AAUl2W"
in this case is there any process by which i can check user validity.?
If it's already hashed, what about:
if($user->password === $request->password)
Give you back a boolean
By default, Laravel currently uses bcrypt algorithm for hashing.
In PHP a random salt is provided to anything you hash. Meaning if you were to have the same thing multiple times, it can give different results. This is to prevent security risks, such as Rainbow table attacks, where someone can lookup your hashed value, and find the original value.
Therefore it is NOT possible to do something like this:
$user = User::where('password', $hashedPassword)->first();
See:
https://www.php.net/manual/en/function.password-hash.php

laravel 5.6 convert hashed password to normal password?

There is no option to convert hashed text back to plain text. Thats the reason why we use that method to store password - only the author of a password can know the real value - nobody else (developers and someone who can stole passwords). The popular method used to break hashed password is called "brute force attack" and is based on comparing already known hashed values of popular passwords to existing ones in database.
Now i need to show current password when user change password. but hash password cant not return back.
how to solve this issue?
convert hashed password to normal password?
Encryption is a two-way function; what is encrypted can be decrypted with the proper key.
Hashing is a one-way function that scrambles plain text to produce a unique message digest. With a properly designed algorithm, there is no way to reverse the hashing process to reveal the original password.
Now i need to show current password when user change password. but hash password cant not return back. how to solve this issue?
You do not need to show the password to anyone, including the owner of the password.
If you want to check, you can use check method, allows you to verify that a given plain-text string corresponds to a given hash.
if (Hash::check('plain-text', $hashedPassword)) {
// The passwords match...
}

Laravel Password Encryption Parameters to decrypt the code

I have some different requirement, i don't want to decode the password, but i am building some other app based on SAME DATABASE for LOGIN so what i can do to "encrypt the password value so that it matches the backend password encrypted code".
I want to provide LOGIN from CODEIGNITOR app where data base is created by admin app in LARAVEL ... this is the issue...
So through CodeIgnitor if someone is LOGIN the password will be encrypted equivalent hash encrypted laravel application code.
The Encrypted Password is
$2y$10$cwd15HRgON0ytqkkV5F9zupfUOkqaii7fpbB9Kjd9I7W46LRYY0Km
And the real PASSWOORD is
123456
Please help...
Caddy DZ's answer is right, but to better answer your question you should know that every time you generate a new password with bcrypt function, a new random salt is used.
This leads you to end up getting a different hash for the same password each time you generate one.
The only way you have to verify the correctness of the password, is to use a built-in php function called password_verify.
That function will hash your password (that you provide as a second argument) with the same salt that has been used to generate the stored password (the salt to use is stored in the password hash) you already have in the database:
$password = '123456';
$saved = 'your stored hash';
if (password_verify($password, $saved)) {
echo 'Correct password.';
}
You can check the documentation about password_verify
This is not standard encryption that can be decrypted, this is hashing which is only one (1) way encryption..
To make this work in, you need to use the same hashing algorithm between the two apps (Laravel and CodeIgniter)
For instance laravel uses bcrypt by default to hash the password, so you need to configure CodeIgniter to use the same or vice versa.
bcrypt for codeigniter

Laravel - user login

I use Laravel 5.4 and need to login user in my system. I have next login.blade.php
where i have email and password field. In my controller I have next
protected function log() {
$email=Input::get('email');
$pass=Input::get('password');
$user = DB::select("SELECT * FROM users where email = '".$email."' and password = '".$pass."'");
foreach($user as $users){
if(Input::get('email') == $users->email){
return redirect('/');
}else{
return view('site.warning');
}
}
}
How can I return logged user in my redirect('/') and show them in my site.
Any idea?
Use the attempt() method:
if (Auth::attempt(['email' => $request->email, 'password' => $request->password])) {
From the docs:
The attempt method accepts an array of key / value pairs as its first argument. The values in the array will be used to find the user in your database table. So, in the example above, the user will be retrieved by the value of the email column. If the user is found, the hashed password stored in the database will be compared with the password value passed to the method via the array.
This method will work for you if you're using bcrypt() or Hash::make() to generate password hash.
Please do not create your own login system!
Now that's out of the way the explanation.
There is (almost) no good reason to create your own login system, as your code already showed. Your current code is very VERY insecure due to storing passwords in plain text. Please read up on resent security advice.
The even better option is using Laravels build-in auth.
https://laravel.com/docs/5.4/authentication
If you do try to use this build-in authentication methods you will be able to get the current authenticated user by using Auth::user() this can be used in your blade files as well as in your controllers.
You cannot (maybe you can) but you certainly should't store user's password unhashed. Laravel has build artisan command: php artisan make:auth. You may use it, and retrieve him in the show method for example (thro the URL, passing id). Or just retrieve him via Auth::user(). Planty of choices.

Laravel 5.4: Password reset token not the same as email token

I have a slight problem after upgrading to laravel 5.4
When i do a password reset, the email gets generated and sent perfectly, however the token it saves to the user record in the database is as follows:
$2y$10$N0WFuqEkEIFto.CazxYLdOUmY1X9tBHfvDn8iWKUdlq2W9uOc00Ku
But the token it sends to the user to do a password reset is:
bc1c82830bc8ad1356aa5e2a2a5a342ae6c6fabd385add503795cca1a1993e15
My question is why are the two tokens different. and how do i perform a check now to validate if the token exists in the database as i need to get the email address to post to the reset controller.
Thanx in advance.
Token you store in database is hashed same as your password column in users table.
However the token you recieve is not hashed. Thats why they are different
Due to get this password ;
$2y$10$N0WFuqEkEIFto.CazxYLdOUmY1X9tBHfvDn8iWKUdlq2W9uOc00Ku
you have to do
Hash::make('bc1c82830bc8ad1356aa5e2a2a5a342ae6c6fabd385add503795cca1a1993e15');
And you cannot revert this process backwards.
The token in the database is encrypted with Bcrypt. That's why it is different in the database.
The token will still work when you use it.
The token it stores in the database is the same string, but hashed with bcrypt, a secure and adaptive algorithm based on the Blowfish cipher.
You can see the documentation for the vanilla PHP password_hash() function to see how it's built, and the password_verify() function to verify that the hashed string is valid against an unhashed version of it (what is sent to the user, in this case).
Laravel Hashing
Laravel includes its own hashing objects and facades which are documented.
To create a hash:
$string = 'Hello world.';
$hash = Hash::make($string);
To verify the hash against a plain string:
if (Hash::check($string, $hash)) {
// The passwords match...
}
Note: In Laravel 5.4, the email token changed from SHA256 to bcrypt in an undocumented change (as issue #18570 shows), so bear that in mind if you are upgrading from Laravel 5.3 or lower.

Resources