微软企业库是开源的,原本是无法对数据库配置的连接字符串进行加密的,但是既然是开源的那就把源码下载下来,想怎么改就怎么改,比如说我这种改法,把Database类的ConnectionString由只读变为可写,那么便可如下方代码一样,对数据库的加密连接字符串进行解密了:
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Data;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
namespace ShiYanXiangMu
{
public static class DBHelper
{
/// <summary>
/// 创建Database对象
/// </summary>
/// <param name="connectionStrings">使用的连接字符串名称,如果传空则使用配置文件中默认指定的</param>
/// <param name="secretKey">如果连接字符串为DES密文,则传输DES解密密钥,如果为明文则传空即可</param>
/// <returns></returns>
static Database getDb(string connectionStrings = null, string secretKey = null)
{
DatabaseFactory.SetDatabaseProviderFactory(new DatabaseProviderFactory(new SystemConfigurationSource(false).GetSection), false);
Database db;
if (string.IsNullOrEmpty(connectionStrings))
{
db = DatabaseFactory.CreateDatabase();
}
else
{
db = DatabaseFactory.CreateDatabase(connectionStrings);
}
if (!string.IsNullOrEmpty(secretKey))//如果密钥入参不为空,那么使用该密钥对连接字符串进行解密
{
db.ConnectionString = Decrypt(db.ConnectionString, secretKey);
}
return db;
}
public static DataTable GetTableBySql(string sql, DbParameter[] parameters = null, DbTransaction trans = null, string connectionStrings = null, string secretKey = null)
{
Database db = getDb(connectionStrings,secretKey:"19950710");
DbCommand command = db.GetSqlStringCommand(sql);
if (parameters != null)
{
foreach (DbParameter param in parameters)
{
db.AddInParameter(command, param.ParameterName, param.DbType, param.Value);
}
}
DataTable dt = null;
if (trans != null)
{
dt = db.ExecuteDataSet(command, trans).Tables[0];
}
else
{
dt = db.ExecuteDataSet(command).Tables[0];
}
if (dt != null)
{
dt.TableName = "tableName";//增加一个表名称,防止WCF方式因为TableName为空出错
}
return dt;
}
/// <summary>
/// DES加密
/// </summary>
/// <param name="str">需要加密的</param>
/// <param name="sKey">密匙</param>
/// <returns></returns>
private static string Encrypt(string str, string sKey)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
byte[] inputByteArray = Encoding.Default.GetBytes(str);
des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);// 密匙
des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);// 初始化向量
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
var retB = Convert.ToBase64String(ms.ToArray());
return retB;
}
/// <summary>
/// DES解密
/// </summary>
/// <param name="pToDecrypt">需要解密的</param>
/// <param name="sKey">密匙</param>
/// <returns></returns>
private static string Decrypt(string pToDecrypt, string sKey)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
byte[] inputByteArray = Convert.FromBase64String(pToDecrypt);
des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
// 如果两次密匙不一样,这一步可能会引发异常
cs.FlushFinalBlock();
return System.Text.Encoding.Default.GetString(ms.ToArray());
}
}
}
下面链接提供已进行修改的微软企业库dll文件,这是根据最新的企业库6作的修改,改动也就是上面所述的Database类的ConnectionString属性,别的都是原汁原味的功能,如有依赖微软企业库,又要对数据库连接字符串进行加密的同学可以拿去使用。