繁体   English   中英

如何在Entity Framework Code First中加密数据?

[英]How do I encrypt data in Entity Framework Code First?

我一直在尝试并且未能找到使用Entity Framework Code First加密SQL数据的好方法。 我必须在前面加上我在Azure中托管并且无法访问本机SQL加密。

SecurEntity获取一个页面,我已经完全实现了一种利用SaveChanges和ObjectMaterialized来处理实体加密/解密的方法,但在测试中我发现这一点太不可靠了。

以下是一些实现的示例:

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

我已经看到其他帖子通过辅助属性手动加密/解密,如下所示:

public Value { get; set; }

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

这肯定会奏效,但我发现这种方法不太理想。 使用这种方法时,所有开发人员都必须浏览所有加密属性,以找出他们可以使用的属性。

最理想的解决方案是让我能够在数据访问级别覆盖每个值的获取/设置。 有没有办法做到这一点? 如果没有,我如何使用Entity Framework - Code First实现数据加密,以便易于维护和使用?

我有好消息。 我使用SaveChanges / ObjectMaterialized方法遇到的不稳定性是由于在DbContext实际执行保存之前不会调用DetectChanges()

在从ObjectStateManager提取Added / Modified记录之前,我可以通过调用DetectChanges()来解决这个问题。 这清除了导致不一致加密行为的任何对象状态怪异。

结果代码是:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM