如何首先加密实体框架代码中的数据? [英] How do I encrypt data in Entity Framework Code First?

查看:199
本文介绍了如何首先加密实体框架代码中的数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试,没有找到一个很好的方法来加密SQL数据与实体框架代码首先。我必须说明这一点,我在Azure中托管,不能访问本地SQL加密。



SecurEntity ,我已经完全实现了一种利用SaveChanges和ObjectMaterialized来处理实体的加密/解密的方法,但是在测试中我发现这是不可靠的使用。 / p>

这是一些实现的示例:

  public override int SaveChanges()
{
var pendingEntities =((IObjectContextAdapter)this).ObjectContext.ObjectStateManager
.GetObjectStateEntries(EntityState.Added | EntityState.Modified)
.Where(en = >!en.IsRelationship).ToList();

foreach(在pendingEntities中的var entry)//加密所有待处理的更改
EncryptEntity(entry.Entity);

int result = base.SaveChanges();

foreach(在pendingEntities中的var entry)//解密更新的实体以继续使用
DecryptEntity(entry.Entity);

返回结果;
}

void ObjectMaterialized(object sender,ObjectMaterializedEventArgs e)
{
DecryptEntity(e.Entity);
}

我看过其他通过二级属性手动加密/解密的帖子,如所以:

  public Value {get;组; 

[NotMapped]
public DecryptedValue
{
get {return Decrypt(this.Value); }
set {this.Value = Encrypt(value); }
}

这绝对有效,但是我发现这种方法是..不太理想当使用这种方法时,所有开发人员都必须通过所有加密属性来查找可以使用的属性。



最理想的解决方案是让我能够以覆盖数据访问级别上每个值的获取/设置。有没有办法做到这一点?如果没有,我该如何使用Entity Framework实现数据加密?首先,这样可以很容易地维护和使用?

解决方案

我有好消息。我使用SaveChanges / ObjectMaterialized方法遇到的不稳定性是由于事实上,直到DbContext实际执行保存才调用 DetectChanges()



我可以通过调用 DetectChanges()来解决这个问题,然后再从 ObjectStateManager 。这清除了导致加密行为不一致的任何对象状态异常。



生成的代码是:

  public override int SaveChanges()
{
var contextAdapter =((IObjectContextAdapter)this);

contextAdapter.ObjectContext.DetectChanges();

var pendingEntities = contextAdapter.ObjectContext.ObjectStateManager
.GetObjectStateEntries(EntityState.Added | EntityState.Modified)
.Where(en =>!en.IsRelationship).ToList( );

foreach(在pendingEntities中的var entry)//加密所有待处理的更改
EncryptEntity(entry.Entity);

int result = base.SaveChanges();

foreach(在pendingEntities中的var entry)//解密更新的实体以继续使用
DecryptEntity(entry.Entity);

返回结果;
}

编辑 - 添加了一个示例DataContext来查看我的用于加密所有实体的端到端解决方案。注意:您不必使用自定义属性来加密属性。 来源


I've been trying and failing to figure out a good approach to encrypting SQL data with the Entity Framework Code First. I must preface this with that I am hosting in Azure and do not have access to native SQL encryption.

Taking a page from SecurEntity, I have fully implemented an approach that utilizes SaveChanges and ObjectMaterialized to handle the encrypting/decrypting of the entities, but in testing I have found this has been far too unreliable to use.

Here is a sample of some of the implementation:

public override int SaveChanges()
{
    var pendingEntities = ((IObjectContextAdapter)this).ObjectContext.ObjectStateManager
        .GetObjectStateEntries(EntityState.Added | EntityState.Modified)
        .Where(en => !en.IsRelationship).ToList();

    foreach (var entry in pendingEntities) //Encrypt all pending changes
        EncryptEntity(entry.Entity);

    int result = base.SaveChanges();

    foreach (var entry in pendingEntities) //Decrypt updated entities for continued use
        DecryptEntity(entry.Entity);

    return result;
}

void ObjectMaterialized(object sender, ObjectMaterializedEventArgs e)
{
    DecryptEntity(e.Entity);
}

I've seen other posts that manually encrypt/decrypt via secondary properties, like so:

public Value { get; set; }

[NotMapped]
public DecryptedValue
{
    get { return Decrypt(this.Value); }
    set { this.Value = Encrypt(value); }
}

This will most definitely work, but I find this approach to be... less than ideal. When using this approach, all the developers have to wade through all the encrypted properties to find which ones they can use.

The most ideal solution would be for me to be able to override the getting/setting of each value at the data-access level. Is there a way to do this? If not, how can I implement data encryption with Entity Framework - Code First so that it will be easy to maintain and work with?

解决方案

I have good news. The instability I was experiencing with the SaveChanges/ObjectMaterialized approach was due to the fact that DetectChanges() isn't called until the DbContext actually performs the save.

I was able to fix this by calling DetectChanges() before I pulled the Added/Modified records from the ObjectStateManager. This cleared up any object state oddities that were causing inconsistent encryption behavior.

The resulting code being:

public override int SaveChanges()
{
    var contextAdapter = ((IObjectContextAdapter)this);

    contextAdapter.ObjectContext.DetectChanges();

    var pendingEntities = contextAdapter.ObjectContext.ObjectStateManager
        .GetObjectStateEntries(EntityState.Added | EntityState.Modified)
        .Where(en => !en.IsRelationship).ToList();

    foreach (var entry in pendingEntities) //Encrypt all pending changes
        EncryptEntity(entry.Entity);

    int result = base.SaveChanges();

    foreach (var entry in pendingEntities) //Decrypt updated entities for continued use
        DecryptEntity(entry.Entity);

    return result;
}

EDIT - Added a sample DataContext to see my end-to-end solution for encrypting all entities. Note: You don't have to use a custom attribute for encrypting properties. Source

这篇关于如何首先加密实体框架代码中的数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆