我需要将一些信息存储在加密的数据库中(而不是哈希,这里不讨论密码),但仍然能够在内存中读取这些信息来验证某些场景(因此需要加密,而不是散列)。
我希望有一种简单明了的方法来识别哪些列应该作为加密存储在数据库中,因为它们将来可能会发生变化。尽管如此,我想知道下面的方法是否适用于IdentityProvider in MVC5和EntityFramework6提供的IdentityProvider。有什么需要注意的注意事项吗?或者这是一个很好的方法来实现这个想法?如果没有,请提供任何指导。
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class StoreSecurelyAttribute : Attribute { }public class UserProfileInfo
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
[Required, StoreSecurely]
public string SomePersonalInformation { get; set; }
}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 ...
}更新:我知道这是一个很大的反射,而且可能会很慢--但是我们不会在加密和解密字段上变得太疯狂,而且我们加密的字段也不会被“每个请求”击中。
发布于 2014-04-05 22:30:12
我会使对受保护数据的读/写操作慎重考虑。
另外,我不知道您是否需要从它编写的相同位置读取数据,但如果不是,则考虑不对称加密来保护数据。这样,写入数据的地方(如web应用程序)只需要访问私钥,而在系统中读取数据的其他地方则只需要访问公钥。
https://stackoverflow.com/questions/22870515
复制相似问题