如何先加密实体框架代码中的数据

本文关键字:数据 代码 框架 何先 加密 实体 | 更新日期: 2023-09-27 17:57:21

我一直在尝试,但未能找到一种先使用实体框架代码加密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); }
}

这绝对会奏效,但我发现这种方法是......不太理想。使用此方法时,所有开发人员都必须遍历所有加密属性,以找到他们可以使用的属性。

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

如何先加密实体框架代码中的数据

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

我能够通过在从ObjectStateManager中提取添加/修改记录之前调用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,以查看用于加密所有实体的端到端解决方案。注意:您不必使用自定义属性来加密属性。源