使用单独的类暴露加密/解密值,通过实体框架加密解密数据:Linq语句失败

时间:2014-12-30 20:28:54

标签: c# linq entity-framework

除了我之前关于实体框架的问题。我的目的是在保存到DB之前加密字段并在从DB读取之前解密字段。我从表User生成类(User.cs)(具有UserName属性(要加密)并且我使用UserName创建了一个单独的类SecureUser早先建议加密/解密的属性。但是我不知道如何将这个新的SecureUser类映射到DB而不是之前的POCO类用户。当我从SecureUser类中用UserName替换UserName时,我的Linq查询失败。我试过做同样的事情部分类的事情,同样的事情发生。 任何建议将不胜感激!

[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); }
    }

}

3 个答案:

答案 0 :(得分:4)

您不能在LINQ to Entities查询中使用SecureUser的{​​{1}}属性,因为它调用UserName方法,LINQ不知道如何将其转换为SQL 。您应该只在常规Decrypt对象上创建[NotMapped]属性,并且应该这样做。像这样:

User

如果这不起作用,那么在对象从LINQ to Objects查询中的数据库返回之后,您将不得不进行解密。像这样:

[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); }
  }
}

答案 1 :(得分:1)

在将用户对象添加到dbcontext时,应设置UserName = Encrypt(model.UserName),其中model是用户为添加它而返回的对象

// 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
    }
}

要使用NotMapped,您应该在using语句中添加此行

using System.ComponentModel.DataAnnotations.Schema;

希望这会对你有所帮助

答案 2 :(得分:1)

您还可以使用对加密数据透明地工作的免费Crypteron CipherDb库。如果您在LINQ查询中使用了某些内容,还有一项允许可搜索加密的功能。

您可以使用[Secure]注释数据模型,或者将属性命名为Secure_SocialSecurityNumberSecure_是关键部分),CipherDb会自动执行数据加密,篡改保护,安全密钥存储,安全密钥分发,缓存,密钥翻转,ACL等。或者,使用CipherObject适配器,您只需使用myObject.Seal()加密对象。

您可以在https://github.com/crypteron/crypteron-sample-apps的GitHub上找到示例应用。您还可以使用Crypteron来保护流,文件,对象,消息队列,noSQL等。

免责声明:我在那里工作,我们有一个免费的社区版本,任何人都可以使用。