今天有个需求是需要加密下NHibernate的连接字符串;
1、先去下了网络的DES加密类;NET好像有自带的,没认真找。
{
private string KEY = " 123321 " ; // 密钥
private byte [] sKey;
private byte [] sIV;
public DESEncrypt()
{
}
/// <summary>
/// 加密方法
/// </summary>
/// <param name="pToEncrypt"> 加密字符串 </param>
/// <param name="keyStr"> 密钥可以为空,默认密钥为"123321" </param>
/// <returns></returns>
public string Encrypt( string pToEncrypt, string keyStr)
{
MemoryStream ms = null ;
CryptoStream cs = null ;
StringBuilder ret = null ;
try
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
if (keyStr == null || keyStr == "" )
keyStr = this .KEY;
// 把字符串放到byte数组中
// 原来使用的UTF8编码,我改成Unicode编码了,不行
byte [] inputByteArray = Encoding.Default.GetBytes(pToEncrypt);
byte [] keyByteArray = Encoding.Default.GetBytes(keyStr);
SHA1 ha = new SHA1Managed();
byte [] hb = ha.ComputeHash(keyByteArray);
sKey = new byte [ 8 ];
sIV = new byte [ 8 ];
for ( int i = 0 ; i < 8 ; i ++ )
sKey[i] = hb[i];
for ( int i = 8 ; i < 16 ; i ++ )
sIV[i - 8 ] = hb[i];
des.Key = sKey;
des.IV = sIV;
ms = new MemoryStream();
cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0 , inputByteArray.Length);
cs.FlushFinalBlock();
ret = new StringBuilder();
foreach ( byte b in ms.ToArray())
{
ret.AppendFormat( " {0:X2} " , b);
}
}
catch (Exception ex)
{
throw new Exception(ex.ToString());
}
finally
{
if ( null != cs) cs.Close();
if ( null != ms) ms.Close();
}
return ret.ToString();
}
/// <summary>
/// 解密方法
/// </summary>
/// <param name="pToDecrypt"> 解密字符串 </param>
/// <param name="keyStr"> 密钥可以为空,默认密钥为"123321" </param>
/// <returns></returns>
public string Decrypt( string pToDecrypt, string keyStr)
{
MemoryStream ms = null ;
CryptoStream cs = null ;
sKey = new byte [ 8 ];
sIV = new byte [ 8 ];
string values = "" ;
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
if (keyStr == null || keyStr == "" )
keyStr = this .KEY;
byte [] inputByteArray = new byte [pToDecrypt.Length / 2 ];
for ( int x = 0 ; x < pToDecrypt.Length / 2 ; x ++ )
{
int i = (Convert.ToInt32(pToDecrypt.Substring(x * 2 , 2 ), 16 ));
inputByteArray[x] = ( byte )i;
}
try
{
byte [] keyByteArray = Encoding.Default.GetBytes(keyStr);
SHA1 ha = new SHA1Managed();
byte [] hb = ha.ComputeHash(keyByteArray);
for ( int i = 0 ; i < 8 ; i ++ )
sKey[i] = hb[i];
for ( int i = 8 ; i < 16 ; i ++ )
sIV[i - 8 ] = hb[i];
des.Key = sKey;
des.IV = sIV;
ms = new MemoryStream();
cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0 , inputByteArray.Length);
cs.FlushFinalBlock();
// 建立StringBuild对象,CreateDecrypt使用的是流对象,必须把解密后的文本变成流对象
values = System.Text.Encoding.Default.GetString(ms.ToArray());
}
catch (Exception ex)
{
throw new Exception( " 文件格式出错 " );
}
finally
{
cs.Close();
ms.Close();
}
return values;
}
}
2、看了下NHibernate配置文件
< section name ="hibernate-configuration"
type ="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" requirePermission ="false" />
</ configSections >
< hibernate-configuration xmlns ="urn:nhibernate-configuration-2.2" >
< session-factory >
<!-- properties -->
< property name ="connection.provider" > NHibernate.Connection.DriverConnectionProvider </ property >
< property name ="connection.driver_class" > NHibernate.Driver.SqlClientDriver </ property >
< property name ="connection.connection_string" > Server=;database=;user id=;password= </ property > < property name ="show_sql" > true </ property >
< property name ="dialect" > NHibernate.Dialect.MsSql2005Dialect </ property >
< property name ="use_outer_join" > true </ property >
< property name ="query.substitutions" > true 1, false 0, yes 'Y', no 'N' </ property >
< property name ="proxyfactory.factory_class" >
NHibernate.ByteCode.Castle.ProxyFactoryFactory,
NHibernate.ByteCode.Castle
</ property >
</ session-factory >
</ hibernate-configuration >
3、找了下资料,发现要重写Configure,所以我想了下自定了个类
{
public CustomDriverConnectionProvider(): base ()
{
}
public override void Configure(IDictionary < string , string > settings)
{
string conn = settings[Environment.ConnectionString];
DESEncrypt des = new DESEncrypt();
settings[Environment.ConnectionString] = des.Decrypt(conn, null );
base .Configure(settings);
}
}
然后将
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
替换成<property name="connection.provider">DataDrawoff.Interface.CustomDriverConnectionProvider</property>
后面NHibernate报错,网上和帮助文档都没如何自定义provider资料(谁知道如何做请告之~~),无奈之下换了种办法:
在NHibernate初始化Configuration文件时候解密即可(当然你要先将连接字符串加密)
cfg.Properties[ " connection.connection_string " ] = Global.Decrypt(cfg.Properties[ " connection.connection_string " ], null ); // 解密
配置文件连接字符串改成类似
当然如果嫌加密字符串长度加密太多,可以只加密数据库名,用户名和密码配置项即可。
这个基本满足了要求,当然要更安全,还要把操作数据库的DLL和加密密钥的DLL混淆;(这个有时间在去尝试下)
4、后面部署碰到本机调试没问题,在服务器调试一直报错,最后找了半天发现时NET2.0框架 需要装个SP1补丁包;
以后要注意了这些框架装完都要找下是否还需要补丁包;