Encrypting and decrypting data using NHibernate

后端 未结 2 1794
渐次进展
渐次进展 2021-02-02 04:01

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

2条回答
  •  一整个雨季
    2021-02-02 04:37

    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;
            }
        }
    }
    

提交回复
热议问题