NHibernate 加密数据库连接字符串以及部署安装碰到的问题

今天有个需求是需要加密下NHibernate的连接字符串;

1、先去下了网络的DES加密类;NET好像有自带的,没认真找。

代码
public class DESEncrypt
{
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配置文件

代码
<configSections>

<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 class CustomDriverConnectionProvider : NHibernate.Connection.DriverConnectionProvider
{
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文件时候解密即可(当然你要先将连接字符串加密)

NHibernate.Cfg.Configuration cfg = new Configuration();
cfg.Properties[
"connection.connection_string"] = Global.Decrypt(cfg.Properties["connection.connection_string"], null);//解密

配置文件连接字符串改成类似

代码
<property name="connection.connection_string">123E0E1DE42F3172025DA161423E580567ED047841A6A3B8704C34A0C04AFC713E055FD4D8442F708295A1EC153CDD96A624C0926BD3B634716BB095F7C40831FF00AA0CA2C4B5A4F0E071F16428940C069E28F0B83A82A135FABFEFA</property>

 当然如果嫌加密字符串长度加密太多,可以只加密数据库名,用户名和密码配置项即可。

这个基本满足了要求,当然要更安全,还要把操作数据库的DLL和加密密钥的DLL混淆;(这个有时间在去尝试下) 

4、后面部署碰到本机调试没问题,在服务器调试一直报错,最后找了半天发现时NET2.0框架 需要装个SP1补丁包

以后要注意了这些框架装完都要找下是否还需要补丁包;

原文地址:https://www.cnblogs.com/xfoolishpig/p/1907147.html