2

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.

JuniorDev
  • 163
  • 2
  • 12

1 Answers1

6

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';
}
dparoli
  • 8,891
  • 1
  • 30
  • 38
  • Okay. I've tried that. If I register a new user I encrypt the user email. Now in AuthenticatesUsers.php credentials method, I do a return 'email' => decrypt($request->email) ... - which is only giving me a "The payload is invalid. " – JuniorDev Aug 03 '19 at 22:53
  • of course, $request->email is the normal email. without any encryption. So this can't work. I don't know where the login is calling for the user, so I can check the email there. – JuniorDev Aug 03 '19 at 23:01
  • You can use mutators, so you don't have to worry where to encrypt or decrypt in your code, I have edited the answer. – dparoli Aug 03 '19 at 23:07
  • I've used the mutators. Also I did all changes which was neccessary to use the username. I can now login with username and so on. Still, if I want to reset the password, laravel auth is trying to get the email, which is still encrypted. I don't really understand why laravel is not decrypting the email, cause I have the decrypt email attribute mutator in my user model – JuniorDev Aug 04 '19 at 07:50
  • Okay, I've found the error. In my user factory for test users, i'm encrypting the emails. But since I have this mutator which is also encrypting a email if it get's set. The email was encrypted twice. Thats why the decrypt, wasn't able to decrypt it properly. – JuniorDev Aug 04 '19 at 08:32
  • since I've removed the encrypt from the factory and only the user mutator is still there, it works – JuniorDev Aug 04 '19 at 08:32
  • Yes, you have to use enc/decrypt only in the mutators. Please consider accepting and upvoting the answer if it works. – dparoli Aug 04 '19 at 08:38