首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用EF6和身份提供程序安全地存储列数据

使用EF6和身份提供程序安全地存储列数据
EN

Stack Overflow用户
提问于 2014-04-04 18:34:50
回答 1查看 706关注 0票数 1

我需要将一些信息存储在加密的数据库中(而不是哈希,这里不讨论密码),但仍然能够在内存中读取这些信息来验证某些场景(因此需要加密,而不是散列)。

我希望有一种简单明了的方法来识别哪些列应该作为加密存储在数据库中,因为它们将来可能会发生变化。尽管如此,我想知道下面的方法是否适用于IdentityProvider in MVC5和EntityFramework6提供的IdentityProvider。有什么需要注意的注意事项吗?或者这是一个很好的方法来实现这个想法?如果没有,请提供任何指导。

  • 为了定义列(代码优先),我创建了一个名为"StoreSecurelyAttribute“的属性,它可以应用于代码优先模型中的不同属性。

代码语言:javascript
复制
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class StoreSecurelyAttribute : Attribute { }
  • 然后,我可以将该属性应用于任何需要安全存储的列(目前只支持字符串)。

代码语言:javascript
复制
public class UserProfileInfo
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    [Required, StoreSecurely]
    public string SomePersonalInformation { get; set; }
}
  • 然后在我的ApplicationDbContext构造器中添加以下内容:

代码语言:javascript
复制
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext() : base("DefaultConnection", false)
    {
        var ctx = ((IObjectContextAdapter) this).ObjectContext;
        ctx.ObjectMaterialized += OnObjectMaterialized;
        ctx.SavingChanges += OnSavingChanges;
    }

    void OnSavingChanges(object sender, EventArgs e)
    {
        foreach (var entry in ((ObjectContext) sender).ObjectStateManager.GetObjectStateEntries(EntityState.Added |
                                                                                  EntityState.Modified))
        {
            foreach (var propInfo in entry.Entity.GetType().GetProperties()
                .Where(prop => prop.PropertyType == typeof(string) && Attribute.IsDefined(prop, typeof(StoreSecurelyAttribute))))
            {
                var plainTextValue = propInfo.GetValue(entry.Entity) as string;
                // TODO: encrypt using injected encryption provider
                var encryptedValue = Encrypt(plainTextValue); 
                propInfo.SetValue(entry.Entity, encryptedValue);
            }
        }
    }

    void OnObjectMaterialized(object sender, ObjectMaterializedEventArgs e)
    {
        foreach (var propInfo in e.Entity.GetType().GetProperties()
                .Where(prop => prop.PropertyType == typeof(string) && Attribute.IsDefined(prop, typeof(StoreSecurelyAttribute))))
            {
                var encryptedValue = propInfo.GetValue(e.Entity) as string;
                // TODO: decrypt using injected encryption provider
                var plainTextValue = Decrypt(encryptedValue);
                propInfo.SetValue(e.Entity, plainTextValue);
            }
    }
    public override int SaveChanges()
    {
        // Hold onto them before their state changes and they're no longer "added" or "modified"
        var entries = ChangeTracker.Entries().Where(x => x.State == EntityState.Added || x.State == EntityState.Modified).ToList();

        // Go Ahead and save...
        var result = base.SaveChanges();

        // After saving to db, we want our local hydrated object to be "correct" so... decrypt...
        foreach (var entry in entries)
        {
            foreach (var propInfo in entry.Entity.GetType().GetProperties()
                .Where(prop => prop.PropertyType == typeof(string) && Attribute.IsDefined(prop, typeof(StoreSecurelyAttribute))))
            {
                var encryptedValue = propInfo.GetValue(entry.Entity) as string;
                var plainTextValue = Decrypt(encryptedValue);
                propInfo.SetValue(entry.Entity, plainTextValue);
            }
        }

        return result;
    }
// ... snip ...
}

更新:我知道这是一个很大的反射,而且可能会很慢--但是我们不会在加密和解密字段上变得太疯狂,而且我们加密的字段也不会被“每个请求”击中。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-04-05 22:30:12

我会使对受保护数据的读/写操作慎重考虑。

另外,我不知道您是否需要从它编写的相同位置读取数据,但如果不是,则考虑不对称加密来保护数据。这样,写入数据的地方(如web应用程序)只需要访问私钥,而在系统中读取数据的其他地方则只需要访问公钥。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22870515

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档