4

I'm using Entity Framework Model First in my project with VS2010.

I'm wondering if there is a way to set the field password to be encrypted in .edmx window or Properties windows maybe. I don't want to change the generated .cs file since it will be covered each time I modify the model.

Ovilia
  • 7,066
  • 12
  • 47
  • 70
  • 3
    You generally don't want passwords to be encrypted with a reversable algorithm. You want to hash the password with a salt. – PHeiberg Jul 30 '12 at 08:27

2 Answers2

5

EF doesn't have any built in support for encryption and it also doesn't have support for database encryption mechanism (unless you are using transparent encryption in SQL Server which will encrypt whole database).

As a workaround you can do centralized encryption and decryption in your application. Here is high level idea:

  • Use a string property for your encrypted data - this property will be represented as nvarchar column in target database
  • Override SaveChanges method in your ObjectContext or DbContext inherited partial class (or handle SavingChanges event for ObjectContext inherited class). In this method / handler search for all instances of your entity which are in Added or Modified state (use ObjectStateManager or DbChangeTracker), take the value from the property which should be encrypted, encrypt it and store encrypted value back to the property in Base64 format. In case of SaveChanges override call base.SaveChanges after you encrypted property for all instances.
  • Handle ObjectMaterialized even on ObjectContext inherited class (in DbContext you will have to use IObjectContextAdapter to get ObjectContext instance from your DbContext instance), take the encrypted value from the property, convert it from Base64 format to byte array, decrypt it and store it back to the property. This may lead to some other complications because changing the property value may result in modified state but you should be able to fix it as well.
Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
  • 1
    I implemented this approach, only to find out that in some cases, ObjectMaterialized does not fire. This means that sometimes your data won't be decrypted. (Like when using projections) – Albert Bori Mar 30 '14 at 04:18
1

A simpler option would be to create a partial class which adds a new property which handles encryption and decryption. You would then refer to this new property in your code instead of the Password property in the table object.

Partial Public Class ObjectName
  Public Property PasswordValue As String
    Get
      Return Password.Decrypt()
    End Get
    Set(value As String)
      Password = value.Encrypt()
    End Set
  End Property
End Class

In this case I created extension methods on the string object to do that. I used the code in the following link to do the encryption and decryption:

Encrypt and decrypt a string

Community
  • 1
  • 1
Rono
  • 3,171
  • 2
  • 33
  • 58
  • While a simple work around, this can cause a lot of issues because you're bringing in data-translation logic into your model. This would be better left to either a repository or even the data context as suggested in the accepted answer (currently working on code that used this approach and it's maddening). – Brandon Martinez Mar 05 '14 at 20:06
  • 1
    I disagree. This approach will have better performance for any operations that don't actually care about the encrypted data. Encrypting and decrypting in the repository means taking that hit even when the current operation was only looking for something innocuous like a user account's name or email address. Doing it THIS way, you only take the encryption/decryption hit when you actually talk about the password field in code. – Mel Dec 12 '14 at 14:50