Question

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.

Était-ce utile?

La solution

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.

Autres conseils

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.

Please find following method which will get you a password hash:

    public static string GetPasswordHash(this string password)
    {
        using (var sha1 = new SHA1Managed())
        {
            var hash = Encoding.UTF8.GetBytes(password);
            var generatedHash = sha1.ComputeHash(hash);
            var generatedHashString = Convert.ToBase64String(generatedHash);
            return generatedHashString;
        }
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top