-
-
Save ByteDecoder/837ae6887b3b2361c407266ec3b09098 to your computer and use it in GitHub Desktop.
.NET EntityFramework Encryption Example (C#)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class MyDB : IdentityDbContext<User> | |
{ | |
//DBSet properties go here | |
public MyDB() | |
{ | |
((IObjectContextAdapter)this).ObjectContext.ObjectMaterialized += new ObjectMaterializedEventHandler(ObjectMaterialized); | |
} | |
#region Encryption | |
public override int SaveChanges() | |
{ | |
var contextAdapter = ((IObjectContextAdapter)this); | |
contextAdapter.ObjectContext.DetectChanges(); //force this. Sometimes entity state needs a handle jiggle | |
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; | |
} | |
public override async Task<int> SaveChangesAsync(System.Threading.CancellationToken cancellationToken) | |
{ | |
var contextAdapter = ((IObjectContextAdapter)this); | |
contextAdapter.ObjectContext.DetectChanges(); //force this. Sometimes entity state needs a handle jiggle | |
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); | |
var result = await base.SaveChangesAsync(cancellationToken); | |
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); | |
} | |
private void EncryptEntity(object entity) | |
{ | |
//Get all the properties that are encryptable and encrypt them | |
var encryptedProperties = entity.GetType().GetProperties() | |
.Where(p => p.GetCustomAttributes(typeof(Encrypted), true).Any(a => p.PropertyType == typeof(String))); | |
foreach (var property in encryptedProperties) | |
{ | |
string value = property.GetValue(entity) as string; | |
if (!String.IsNullOrEmpty(value)) | |
{ | |
string encryptedValue = EncryptionService.Encrypt(value); | |
property.SetValue(entity, encryptedValue); | |
} | |
} | |
} | |
private void DecryptEntity(object entity) | |
{ | |
//Get all the properties that are encryptable and decyrpt them | |
var encryptedProperties = entity.GetType().GetProperties() | |
.Where(p => p.GetCustomAttributes(typeof(Encrypted), true).Any(a => p.PropertyType == typeof(String))); | |
foreach (var property in encryptedProperties) | |
{ | |
string encryptedValue = property.GetValue(entity) as string; | |
if (!String.IsNullOrEmpty(encryptedValue)) | |
{ | |
string value = EncryptionService.Decrypt(encryptedValue); | |
this.Entry(entity).Property(property.Name).OriginalValue = value; | |
this.Entry(entity).Property(property.Name).IsModified = false; | |
} | |
} | |
} | |
#endregion Encryption | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment