為數(shù)據(jù)庫(kù)中的關(guān)鍵字段進(jìn)行加密是必不可少的,特別是一些用戶(hù)密碼,銀行卡賬號(hào)等。現(xiàn)在我們來(lái)說(shuō)一下如何在Nhibernate中創(chuàng)建一個(gè)加密類(lèi)來(lái)為數(shù)據(jù)庫(kù)中的關(guān)鍵字段加密。
讓客戶(hù)滿(mǎn)意是我們工作的目標(biāo),不斷超越客戶(hù)的期望值來(lái)自于我們對(duì)這個(gè)行業(yè)的熱愛(ài)。我們立志把好的技術(shù)通過(guò)有效、簡(jiǎn)單的方式提供給客戶(hù),將通過(guò)不懈努力成為客戶(hù)在信息化領(lǐng)域值得信任、有價(jià)值的長(zhǎng)期合作伙伴,公司提供的服務(wù)項(xiàng)目有:域名注冊(cè)、網(wǎng)絡(luò)空間、營(yíng)銷(xiāo)軟件、網(wǎng)站建設(shè)、荔波網(wǎng)站維護(hù)、網(wǎng)站推廣。1 創(chuàng)建一個(gè)接口:IEncryptor
public interface IEncryptor
{
string Encrypt(string plainText);
string Decrypt(string encryptedText);
string EncryptionKey { get; set; }
}
2 再創(chuàng)建一個(gè)繼承它的子類(lèi):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 再創(chuàng)建一個(gè)類(lèi):DESEncryptor
public class DESEncryptor : SymmetricEncryptorBase
{
public DESEncryptor()
:base(new DESCryptoServiceProvider())
{ }
}
4 再新建一個(gè)類(lèi):EncryptedString,通過(guò)這個(gè)類(lèi)來(lái)調(diào)用前面的DESEncryptor來(lái)加密解密字符串
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.這個(gè)加密類(lèi)到此就完成了?,F(xiàn)在我們來(lái)創(chuàng)建一個(gè)Account對(duì)象來(lái)測(cè)試。
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; }
}
重要的是定義相應(yīng)的Account.hbm.xml文件:
EncryptedStringExample.DESEncryptor,
EncryptedStringExample
12345678
在一個(gè)新建的控制臺(tái)應(yīng)用程序中,我們新建一個(gè)Account對(duì)象來(lái)測(cè)試一下:
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.打開(kāi)數(shù)據(jù)庫(kù),看到存儲(chǔ)在其中的字段已經(jīng)被加密了.
現(xiàn)在我們從數(shù)據(jù)庫(kù)中取出該字段看看。因?yàn)橹挥幸粭l記錄,我就只取第一條了。
private static Account GetAccount(NHibernate.ISession session)
{
return session.QueryOver().Take(1).SingleOrDefault();
}
在Main方法中增加兩行代碼:
Account account = GetAccount(session);
Console.WriteLine(account.CardNumber);
我們可以看到控制臺(tái)上顯示出來(lái)的值為:
可以看出解密正確。
源碼下載:點(diǎn)我。項(xiàng)目中的EncryptedStringExample與EncryptedStringTest