Nhibernate3.0cookbook学习笔记创建一个加密类-创新互联

为数据库中的关键字段进行加密是必不可少的,特别是一些用户密码,银行卡账号等。现在我们来说一下如何在Nhibernate中创建一个加密类来为数据库中的关键字段加密。

让客户满意是我们工作的目标,不断超越客户的期望值来自于我们对这个行业的热爱。我们立志把好的技术通过有效、简单的方式提供给客户,将通过不懈努力成为客户在信息化领域值得信任、有价值的长期合作伙伴,公司提供的服务项目有:域名注册、网络空间、营销软件、网站建设、荔波网站维护、网站推广。

1 创建一个接口:IEncryptor

public interface IEncryptor
    {
string Encrypt(string plainText);
string Decrypt(string encryptedText);
string EncryptionKey { get; set; }
    }

2 再创建一个继承它的子类:SymmetricEncryptorBase

public class SymmetricEncryptorBase : IEncryptor
    {
private readonly SymmetricAlgorithm _cryptoProvider;
private byte[] _myBytes;
protected SymmetricEncryptorBase(
        SymmetricAlgorithm cryptoProvider)
        {
            _cryptoProvider= cryptoProvider;
        }

#region IEncryptor 成员
   public string EncryptionKey { get; set; }      

///    /// 加密,利用CryptoStream
///    ///    ///    public string Encrypt(string plainText)
        {
var bytes = GetEncryptionKeyBytes();
using (var memoryStream = new MemoryStream())
            {
                ICryptoTransform encryptor= _cryptoProvider
                .CreateEncryptor(bytes, bytes);
using (var cryptoStream = new CryptoStream(
                memoryStream, encryptor, CryptoStreamMode.Write))
                {
using (var writer = new StreamWriter(cryptoStream))
                    {
                       
                        writer.Write(plainText);
                        writer.Flush();
                        cryptoStream.FlushFinalBlock();
return Convert.ToBase64String(
                        memoryStream.GetBuffer(),
0,
                        (int)memoryStream.Length);
                    }
                }
            }
        }

//获取密钥   private byte[] GetEncryptionKeyBytes()
        {
if (_myBytes == null)
                _myBytes= Encoding.ASCII.GetBytes(EncryptionKey);
return _myBytes;
        }

///    /// 解密
///    ///    ///    public string Decrypt(string encryptedText)
        {
var bytes = GetEncryptionKeyBytes();
using (var memoryStream = new MemoryStream(
            Convert.FromBase64String(encryptedText)))
            {
                ICryptoTransform decryptor= _cryptoProvider
                .CreateDecryptor(bytes, bytes);
using (var cryptoStream = new CryptoStream(
                memoryStream, decryptor, CryptoStreamMode.Read))
                {
using (var reader = new StreamReader(cryptoStream))
                    {
return reader.ReadToEnd();
                    }
                }
            }
        }

#endregion
    }

3 再创建一个类:DESEncryptor

 public class DESEncryptor : SymmetricEncryptorBase
    {
public DESEncryptor()
            :base(new DESCryptoServiceProvider())
        { }
    }

4 再新建一个类:EncryptedString,通过这个类来调用前面的DESEncryptor来加密解密字符串

public class EncryptedString : IUserType, IParameterizedType
    {
private IEncryptor _encryptor;
public object NullSafeGet( IDataReader rs, string[] names, object owner)
        {
//treat for the posibility of null values object passwordString =
            NHibernateUtil.String.NullSafeGet(rs, names[0]);
if (passwordString != null)
            {
return _encryptor.Decrypt((string)passwordString);
            }
return null;
        }
public void NullSafeSet(IDbCommand cmd,object value,int index)
        {
if (value == null)
            {
                NHibernateUtil.String.NullSafeSet(cmd,null, index);
return;
            }
string encryptedValue = _encryptor.Encrypt((string)value);
            NHibernateUtil.String.NullSafeSet(
            cmd, encryptedValue, index);
        }
public object DeepCopy(object value)
        {
return value == null ? null :
string.Copy((string)value);
        }
public object Replace(object original,
object target, object owner)
        {
return original;
        }
public object Assemble(object cached, object owner)
        {
return DeepCopy(cached);
        }

public object Disassemble(object value)
        {
return DeepCopy(value);
        }
public SqlType[] SqlTypes
        {
get
            {
return new[] { new SqlType(DbType.String) };
            }
        }
public Type ReturnedType
        {
get { return typeof(string); }
        }
public bool IsMutable
        {
get { return false; }
        }
public new bool Equals(object x, object y)
        {
if (ReferenceEquals(x, y))
            {
return true;
            }
if (x == null || y == null)
            {
return false;
            }
return x.Equals(y);
        }
public int GetHashCode(object x)
        {
if (x == null)
            {
throw new ArgumentNullException("x");
            }
return x.GetHashCode();
        }
public void SetParameterValues(
        IDictionary parameters)
        {
if (parameters != null)
            {
var encryptorTypeName = parameters["encryptor"];
                _encryptor= !string.IsNullOrEmpty(encryptorTypeName)
? (IEncryptor)Instantiate(encryptorTypeName)
                :new DESEncryptor();
var encryptionKey = parameters["encryptionKey"];
if (!string.IsNullOrEmpty(encryptionKey))
                    _encryptor.EncryptionKey= encryptionKey;
            }
else
            {
                _encryptor= new DESEncryptor();
            }
        }
private static object Instantiate(string typeName)
        {
var type = Type.GetType(typeName);
return Activator.CreateInstance(type);
        }
    }

 OK.这个加密类到此就完成了。现在我们来创建一个Account对象来测试。

public class Account
    {
public virtual Guid Id { get; set; }
public virtual string EMail { get; set; }
public virtual string Name { get; set; }
public virtual string CardNumber { get; set; }
public virtual int ExpirationMonth { get; set; }
public virtual int ExpirationYear { get; set; }
public virtual string ZipCode { get; set; }
    }

重要的是定义相应的Account.hbm.xml文件:

    
      EncryptedStringExample.DESEncryptor,
      EncryptedStringExample
    12345678                   

 在一个新建的控制台应用程序中,我们新建一个Account对象来测试一下:

 private static void AddAccount(NHibernate.ISession session)
        {
            session.Save(new Account() { 
             CardNumber="45678",
             EMail="bb@qq.com",
             ExpirationMonth=12,
             ExpirationYear=2012,
             Name="gyoung",
             ZipCode="55555"
            });
        }

加密的字段为:CardNumber.打开数据库,看到存储在其中的字段已经被加密了.

现在我们从数据库中取出该字段看看。因为只有一条记录,我就只取第一条了。

private static Account GetAccount(NHibernate.ISession session)
        {
return session.QueryOver().Take(1).SingleOrDefault();
        }

在Main方法中增加两行代码:

  Account account = GetAccount(session);
  Console.WriteLine(account.CardNumber);

我们可以看到控制台上显示出来的值为:

 可以看出解密正确。

 源码下载:点我。项目中的EncryptedStringExample与EncryptedStringTest


网页题目:Nhibernate3.0cookbook学习笔记创建一个加密类-创新互联
文章出自:http://hbruida.cn/article/cseoih.html