Encrypting Decrypting Data via Entity Framework using separate class exposing encrypted/decrypted values: Linq statements fails

c# entity-framework linq

Question

In addition to my earlier question on entity framework. My purpose is to encrypt the field before saving to DB and Decrypt the fields before reading from DB.I have class (User.cs) generated from table User(having UserName property(to be encrypted) and I created a separate class SecureUser with UserName property that isencrypted/decrypted as suggested earlier. But I am not sure how to map this new SecureUser class to DB and not the previous POCO class User. My Linq queries fail when I replace UserName with UserName from SecureUser class. I tried doing the same thing with partial classes , same thing happens. Any suggestions will be greatly appreciated !

[Table("Users")]
public class User
{

    #region database table column mapped fields
    [Key]
    [Required]
    public Int32 UserID { set; get; }

    [Required]
    [MaxLength(50)]
    public String UserName { set; get; }

    [Required]
    public Int32 CustID { set; get; }

//created the separate class as
public class SecureUser // UserViewModel
{
    // 
    private readonly User _user;

   public SecureUser(User user)
    {
        _user = user;
    }

    public string UserName
    {
        get { return Decrypt(_user.UserName); }
        set { _user.UserName = Encrypt(value); }
    }

}

1
3
12/30/2014 8:28:54 PM

Accepted Answer

On adding the user object to the dbcontext, you should set UserName=Encrypt(model.UserName) where model is the object returned by the user for adding it

// before adding the model to the dbcontext
model.UserName=Encrypt(mode.UserName);
db.Users.Add(model);
db.SaveChanges();

[Table("Users")]
public class User
{
    #region database table column mapped fields
    [Key]
    [Required]
    public Int32 UserID { set; get; }

    [Required]
    [MaxLength(50)]
    public String UserName { set; get; } // this field will be encrypted field

    [Required]
    public Int32 CustID { set; get; }

    [NotMapped]
    public string DecryptedUserName
    {
        get { return Decrypt(UserName); }  // this you can display it to the user
    }
}

to use the NotMapped, you should add this line in the using statements

using System.ComponentModel.DataAnnotations.Schema;

hope this will help you

1
12/31/2014 2:55:45 PM

Popular Answer

You can't use SecureUser's UserName property in a LINQ to Entities query because it's calling the Decrypt method, which LINQ has no idea on how to translate that into SQL. You should probably just create a [NotMapped] property on your regular User object, and that should do it. Like so:

[Table("Users")]
public class User
{
  #region database table column mapped fields
  [Key]
  [Required]
  public Int32 UserID { set; get; }

  [Required]
  [MaxLength(50)]
  public String UserName { set; get; }

  [Required]
  public Int32 CustID { set; get; }

  [NotMapped]
  public string DecryptedUserName
  {
    get { return Decrypt(this.UserName); }
    set { this.UserName = Encrypt(value); }
  }
}

If that doesn't work, you'll have to do the decryption after the objects have come back from the database inside of a LINQ to Objects query. Something like this:

var users = db.Users.Where(u => u.CustID == someID); //LINQ to Entities
var decryptedUserNames = users.ToList().Select(u => Decrypt(u.UserName)); //LINQ to Objects


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow