Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EF Code First Encrypt/Decrypt Password Property

I have model like below:

public class User 
{
    private string password;
    public string Password
    {
        get { return Decrypt(password); }
        set { password = Encrypt(value); }
    }
}

I want from user code to use just insert and select password easily and see in clear text and want the logic layer to handle the encryption and decryption.

But when selecting, EF will set the value again so the encrypted password gotten from database will be encrypted again for me to get from the client code which is a problem. I also cannot distinguish between an Insert and Select to set conditionals.

I can very well do this:

//Insert
user.Password = Encrypt("123"); //Encrypt or Hash does not matter
context.Users.Add(user);

//Select
var hashedpassword = context.Users.Find(1).Select(u => u.Password).Single();
var unhashed = Decrypt(hashedpassword);

Instead I would like it not to be apparent from client code:

//Insert
user.Password = "123"; //Inserts encrypted password in database
context.Users.Add(user);

//Select
var cleartextpassword = context.Users.Find(1).Select(u => u.Password).Single();

Hope I was able to explain the problem and someone can point me to the right direction. If it is even possible or not.

like image 591
lbrahim Avatar asked Dec 12 '22 06:12

lbrahim


2 Answers

The better solution is indeed to use a Hash.

But a general pattern for injecting some logic:

public class User 
{   
    // the mapped-to-column property 
    protected virtual string PasswordStored
    {
        get ;
        set ;
    }


    [NotMapped]
    public string Password
    {
        get { return Decrypt(PasswordStored); }
        set { PasswordStored = Encrypt(value); }
    }


}

Instead of [NotMapped] you can also use the fluent API to keep EF from storing it directly.

like image 85
Henk Holterman Avatar answered Dec 13 '22 21:12

Henk Holterman


Read and write your entities only from a repository, i.e., through a data access class that you write:

var myEntities = userRepository.GetUserById(id);

then your GetUserById() method can perform the decryption in-place. Then when you do

userRepository.UpdateUser(myUser);

you can encrypt the field again in the UpdateUser() method.

like image 41
Roy Dictus Avatar answered Dec 13 '22 21:12

Roy Dictus