I\'m writing a publicly accessible web application which will contain personal user data, such as names and birth dates, and I\'m required to encrypt this data in a form that w
I would create an EncryptionService that encrypts strings using whatever Key you'd like. Then I would make 2 properties in your entity. One that NHibernate interacts with (Encrypted values) and another that you (or other developers) interact with that will automatically encrypt the values.
See: http://kockerbeck.blogspot.com/2009/08/fluent-nhibernate-encrypting-values.html
A sample EncryptionService, User entity and UserMap are below.
public class User
{
private readonly EncryptionService _encryptionService =
new EncryptionService();
public virtual int Id { get; set; }
public virtual DateTime? DateOfBirth
{
get
{
return _encryptionService.DecryptObject(DateOfBirthEncrypted);
}
set
{
DateOfBirthEncrypted= _encryptionService.EncryptString(value.Value
.ToString("yyyy-MM-dd HH:mm:ss"));
}
}
[Obsolete("Use the 'DateOfBirth' property -- this property is only to be used by NHibernate")]
public virtual string DateOfBirthEncrypted { get; set; }
}
public sealed class UserMap : ClassMap
{
public UserMap()
{
WithTable("dbo.[User]");
Id(x => x.Id, "[ID]");
Map(x => x.DateOfBirthEncrypted, "DOB");
}
}
And the EncryptionService:
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace Services
{
public class EncryptionService : IEncryptionService
{
///
/// Decrypts a string
///
///
///
public String DecryptString(string encryptedString)
{
if (String.IsNullOrEmpty(encryptedString)) return String.Empty;
try
{
using (TripleDESCryptoServiceProvider cypher = new TripleDESCryptoServiceProvider())
{
PasswordDeriveBytes pdb = new PasswordDeriveBytes("ENTERAKEYHERE", new byte[0]);
cypher.Key = pdb.GetBytes(16);
cypher.IV = pdb.GetBytes(8);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, cypher.CreateDecryptor(), CryptoStreamMode.Write))
{
byte[] data = Convert.FromBase64String(encryptedString);
cs.Write(data, 0, data.Length);
cs.Close();
return Encoding.Unicode.GetString(ms.ToArray());
}
}
}
}
catch
{
return String.Empty;
}
}
///
/// Encrypts a string
///
///
public String EncryptString(string decryptedString)
{
if (String.IsNullOrEmpty(decryptedString)) return String.Empty;
using (TripleDESCryptoServiceProvider cypher = new TripleDESCryptoServiceProvider())
{
PasswordDeriveBytes pdb = new PasswordDeriveBytes("ENTERAKEYHERE", new byte[0]);
cypher.Key = pdb.GetBytes(16);
cypher.IV = pdb.GetBytes(8);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, cypher.CreateEncryptor(), CryptoStreamMode.Write))
{
byte[] data = Encoding.Unicode.GetBytes(decryptedString);
cs.Write(data, 0, data.Length);
cs.Close();
return Convert.ToBase64String(ms.ToArray());
}
}
}
}
///
/// Decrypts a given value as type of T, if unsuccessful the defaultValue is used
///
///
///
///
///
public T DecryptObject(object value, T defaultValue)
{
if (value == null) return defaultValue;
try
{
Type conversionType = typeof(T);
// Some trickery for Nullable Types
if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
{
conversionType = new NullableConverter(conversionType).UnderlyingType;
}
return (T)Convert.ChangeType(DecryptString(Convert.ToString(value)), conversionType);
}
catch
{
// Do nothing
}
return defaultValue;
}
}
}