SQL Server 2000DBAIISVisual Studio .NET 2003Windows 2003.NET 1.1Windows 2000Windows XP中级开发Visual StudioSQL ServerSQLWindows.NETASP.NETC#
使用 Web 控件在 web.config 中配置安全数据连接





3.00/5 (5投票s)
2005年5月20日

44720

740
这个 C# Web 控件用于配置网站的数据连接。
引言
本文介绍如何使用 web.config 存储和检索 MS SQL 数据库连接字符串。与此同时,也考虑了存储信息的安全性。以下是一个示例 web.config 文件
<APPSETTINGS>
<ADD value="127.0.0.1" key="Server Name" />
<ADD value="hq" key="Database Name" />
<ADD value="false" key="Login Secure" />
<ADD value="jzd" key="User Name" />
<ADD
value="4F4A68462B30794B51743655503470724373593955413D3D"
key="Password"/>
</APPSETTINGS>
在这个 web.config 中的 appSettings
部分,我们提供的 Password
值使用 DES RC2 和 Rijndael 进行加密。为此,您需要在加密类的顶部添加一行:using System.Security.Cryptography;
因此,为了实现这一点,我们需要编写一个加密类、一个数据连接类和一个 Web 控件来操作 web.config。
加密类
这里有一些重写的方法
public string EncryptingHex(string Source, byte[] key, byte[] iv)
public string DecryptingHex(string Source, byte[] key, byte[] iv)
public string EncryptingHex(string Source, string key, string iv)
public string DecryptingHex(string Source, string key, string iv)
public byte[] EncryptingStream(byte[] bytIn,string key,string iv)
public byte[] DecryptingStream(byte[] bytIn, string key, string iv)
using System;
using System.Security.Cryptography;
using System.IO;
using System.Text;
using System.Web;
namespace eReach.Fundamental.Security
{
public class Key
{
#region Private Members
private SymmetricAlgorithm CryptoSvc;
private int KeySize, IVSize;
#endregion
#region Constractors
public Key()
{
CryptoSvc = new RijndaelManaged();
KeySize = 32;
IVSize = 16;
}
public Key(int Crypto)
{
switch (Crypto)
{
case 0:
CryptoSvc = new DESCryptoServiceProvider();
KeySize = 8;
IVSize = 8;
break;
case 1:
CryptoSvc = new RC2CryptoServiceProvider();
KeySize = 8;
IVSize = 8;
break;
case 2:
CryptoSvc = new RijndaelManaged();
KeySize = 32;
IVSize = 16;
break;
}
}
#endregion
#region Private Methods
private byte[] GetLegalKey(string key)
{
if (key.Length < KeySize)
key = key.PadRight(KeySize,' ');
else
{
key = key.Substring(0,KeySize);
}
return ASCIIEncoding.ASCII.GetBytes(key);
}
private byte[] GetLegalIV(string iv)
{
if (iv.Length < IVSize)
iv = iv.PadRight(IVSize,' ');
else
{
iv = iv.Substring(0,IVSize);
}
return ASCIIEncoding.ASCII.GetBytes(iv);
}
private byte HexVal(char chr)
{
byte retvar = 0;
switch (chr)
{
case 'A':
retvar = 10;
break;
case 'B':
retvar = 11;
break;
case 'C':
retvar = 12;
break;
case 'D':
retvar = 13;
break;
case 'E':
retvar = 14;
break;
case 'F':
retvar = 15;
break;
case '9':
retvar = 9;
break;
case '8':
retvar = 8;
break;
case '7':
retvar = 7;
break;
case '6':
retvar = 6;
break;
case '5':
retvar = 5;
break;
case '4':
retvar = 4;
break;
case '3':
retvar = 3;
break;
case '2':
retvar = 2;
break;
case '1':
retvar = 1;
break;
case '0':
retvar = 0;
break;
default:
retvar = 0;
break;
}
return retvar;
}
private string HexEncoding(string hexdest)
{
char[] passchr = hexdest.ToCharArray();
string dest = "";
int first = 0, second = 0;
for (int i = 0; i <= passchr.Length - 1; i += 2)
{
first = HexVal(passchr[i]) * 16;
second = HexVal(passchr[i+1]);
dest += (char)(first + second);
}
return dest;
}
#endregion
#region Protected Method
protected string Encrypting(string Source,byte[] key,byte[] iv)
{
byte[] bytIn =
System.Text.ASCIIEncoding.ASCII.GetBytes(
System.Web.HttpUtility.UrlEncode(Source));
System.IO.MemoryStream ms = new System.IO.MemoryStream();
CryptoSvc.Key = key;
CryptoSvc.IV = iv;
ICryptoTransform encrypto = CryptoSvc.CreateEncryptor();
CryptoStream cs = new CryptoStream(ms, encrypto,
CryptoStreamMode.Write);
cs.Write(bytIn, 0, bytIn.Length);
cs.FlushFinalBlock();
byte[] bytOut = ms.GetBuffer();
int i = 0;
for (i = 0; i < bytOut.Length; i++)
if (bytOut[i] == 0)
break;
return System.Convert.ToBase64String(bytOut, 0, i);
}
private string Decrypting(string Source, byte[] key, byte[] iv)
{
byte[] bytIn =
System.Convert.FromBase64String(Source);
System.IO.MemoryStream ms = new System.IO.MemoryStream(bytIn,
0, bytIn.Length);
CryptoSvc.Key = key;
CryptoSvc.IV = iv;
ICryptoTransform encrypto = CryptoSvc.CreateDecryptor();
CryptoStream cs = new CryptoStream(ms, encrypto,
CryptoStreamMode.Read);
System.IO.StreamReader sr = new System.IO.StreamReader( cs );
string sEncoded = sr.ReadToEnd();
return System.Web.HttpUtility.UrlDecode(sEncoded);
}
protected string Encrypting(string Source,string key,string iv)
{
byte[] bytIn =
System.Text.ASCIIEncoding.ASCII.GetBytes(
System.Web.HttpUtility.UrlEncode(Source));
System.IO.MemoryStream ms = new System.IO.MemoryStream();
CryptoSvc.Key = GetLegalKey(key);
CryptoSvc.IV = GetLegalIV(iv);
ICryptoTransform encrypto = CryptoSvc.CreateEncryptor();
CryptoStream cs = new CryptoStream(ms, encrypto,
CryptoStreamMode.Write);
cs.Write(bytIn, 0, bytIn.Length);
cs.FlushFinalBlock();
byte[] bytOut = ms.GetBuffer();
int i = 0;
for (i = 0; i < bytOut.Length; i++)
if (bytOut[i] == 0)
break;
return System.Convert.ToBase64String(bytOut, 0, i);
}
private string Decrypting(string Source, string key, string iv)
{
byte[] bytIn = System.Convert.FromBase64String(Source);
System.IO.MemoryStream ms = new System.IO.MemoryStream(bytIn,
0, bytIn.Length);
CryptoSvc.Key = GetLegalKey(key);
CryptoSvc.IV = GetLegalIV(iv);
ICryptoTransform encrypto = CryptoSvc.CreateDecryptor();
CryptoStream cs = new CryptoStream(ms, encrypto,
CryptoStreamMode.Read);
System.IO.StreamReader sr =
new System.IO.StreamReader( cs );
string sEncoded = sr.ReadToEnd();
return System.Web.HttpUtility.UrlDecode(sEncoded);
}
#endregion
#region Public Methods
public string EncryptingHex(string Source, byte[] key, byte[] iv)
{
string dest = Encrypting(Source,key,iv);
byte[] hexbty = Encoding.ASCII.GetBytes(dest.ToCharArray());
string hexdest = "";
for (int i = 0; i <= hexbty.Length - 1; i++)
{
hexdest += hexbty[i].ToString("X2");
}
return hexdest;
}
public string DecryptingHex(string Source, byte[] key, byte[] iv)
{
Source = HexEncoding(Source);
return Decrypting(Source,key,iv);
}
public string EncryptingHex(string Source, string key, string iv)
{
string dest = Encrypting(Source,key,iv);
byte[] hexbty = Encoding.ASCII.GetBytes(dest.ToCharArray());
string hexdest = "";
for (int i = 0; i <= hexbty.Length - 1; i++)
{
hexdest += hexbty[i].ToString("X2");
}
return hexdest;
}
public string DecryptingHex(string Source, string key, string iv)
{
Source = HexEncoding(Source);
return Decrypting(Source,key,iv);
}
public byte[] EncryptingStream(byte[] bytIn,string key,string iv)
{
System.IO.MemoryStream ms = new System.IO.MemoryStream();
CryptoSvc.Key = GetLegalKey(key);
CryptoSvc.IV = GetLegalIV(iv);
ICryptoTransform encrypto = CryptoSvc.CreateEncryptor();
CryptoStream cs = new CryptoStream(ms, encrypto,
CryptoStreamMode.Write);
cs.Write(bytIn, 0, bytIn.Length);
cs.FlushFinalBlock();
byte[] bytOut = ms.GetBuffer();
int i = 0;
for (i = 0; i < bytOut.Length; i++)
if (bytOut[i] == 0)
break;
return bytOut;
}
protected byte[] DecryptingStream(byte[] bytIn, string key, string iv)
{
System.IO.MemoryStream ms = new System.IO.MemoryStream(bytIn,
0, bytIn.Length);
CryptoSvc.Key = GetLegalKey(key);
CryptoSvc.IV = GetLegalIV(iv);
ICryptoTransform encrypto = CryptoSvc.CreateDecryptor();
CryptoStream cs = new CryptoStream(ms, encrypto,
CryptoStreamMode.Read);
System.IO.StreamReader sr = new System.IO.StreamReader( cs );
return System.Text.ASCIIEncoding.ASCII.GetBytes(
System.Web.HttpUtility.UrlEncode(sr.ReadToEnd()));
}
#endregion
}
}
数据连接类
这里给出了一些方法
public string GenConfigPassword(string password)
public DataSet GetDataSet(string selectcmd)
public DataSet GetDataSet(string selectcmd,string database)
using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.IO;
namespace eReach.Fundamental.Data
{
/// <summary>
/// Connection
/// </summary>
public class Connection : eReach.Fundamental.Security.Key
{
#region Declares
private string servername = "";
private string dbname = "";
private string username = "";
private string password = "";
private string loginsecure = "";
private string connstr = "";
private const string Key =
"m2pxltd9Qrs7yAjco0eFuh3vb6iw4k8ng5z1";
private const string IV = "d9cz13gmvb67iwhy";
protected SqlConnection conn;
#endregion
#region 构造和析构
public Connection() : base()
{
try
{
servername =
ConfigurationSettings.AppSettings["Server Name"];
dbname =
ConfigurationSettings.AppSettings["Database Name"];
username =
ConfigurationSettings.AppSettings["User Name"];
password =
ConfigurationSettings.AppSettings["Password"];
loginsecure =
ConfigurationSettings.AppSettings["Login Secure"];
if (loginsecure == "true")
connstr = "Data Source=" + servername +
";Initial Catalog=" + dbname +
";Trusted_Connection=yes;Connect Timeout=30";
else
{
connstr = "Data Source=" + servername +
";Initial Catalog=" +
dbname + ";User ID=" +
username + ";Password=" +
this.DecryptingHex(password,Key,IV);
}
conn = new SqlConnection(connstr);
}
catch
{
conn = new SqlConnection();
}
}
~Connection()
{
conn.Close();
}
#endregion
#region Protected Method
protected string GetPrototypeConfigPassword(string password)
{
return this.DecryptingHex(password,Key,IV);
}
#endregion
#region public methods
public string GenConfigPassword(string password)
{
return this.EncryptingHex(password,Key,IV);
}
public DataSet GetDataSet(string selectcmd)
{
try
{
SqlCommand cmd = new SqlCommand(selectcmd,conn);
cmd.CommandTimeout = 30;
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = cmd;
conn.Open();
DataSet ds = new DataSet();
adapter.Fill(ds,"usersbase");
conn.Close();
return ds;
}
catch
{
return (new DataSet());
}
}
public DataSet GetDataSet(string selectcmd,string database)
{
try
{
SqlCommand cmd = new SqlCommand(selectcmd,conn);
cmd.CommandTimeout = 30;
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = cmd;
conn.Open();
conn.ChangeDatabase(database);
DataSet ds = new DataSet();
adapter.Fill(ds,"usersbase");
conn.Close();
return ds;
}
catch
{
return (new DataSet());
}
}
public SqlDataReader GetReader(string selectcmd)
{
try
{
SqlCommand cmd = new SqlCommand(selectcmd, conn);
conn.Open();
SqlDataReader reader = cmd.ExecuteReader();
reader.Read();
return reader;
}
catch
{
return null;
}
}
public int ExecuteSQLCmd(string sqlcmd)
{
try
{
SqlCommand cmd = new SqlCommand(sqlcmd, conn);
conn.Open();
return cmd.ExecuteNonQuery();
}
catch
{
return 0;
}
}
#endregion
}
}
Web 控件
这是我们目标的最后一步。为了编写一个可以方便地操作 web.config 的 Web 控件,请下载 Web 控件源代码并对 password
键进行简单的更新。
#region Events
private void LinkButton1_Click(object sender, EventArgs e)
{
if (this.TextBox1.Text.Trim() != "")
this.AppSettings("Server Name",this.TextBox1.Text.Trim());
if (this.TextBox2.Text.Trim() != "")
this.AppSettings("Database Name",this.TextBox2.Text.Trim());
if (this.CheckBox1.Checked)
this.AppSettings("Login Secure","true");
else
this.AppSettings("Login Secure","false");
if (this.TextBox3.Text.Trim() != "")
this.AppSettings("User Name",this.TextBox3.Text.Trim());
if (this.TextBox4.Text.Trim() != "")
{
if (this.TextBox4.Text.Trim() == this.TextBox5.Text.Trim())
this.AppSettings("Password",
this.ocon.GenConfigPassword(this.TextBox4.Text.Trim()));
else
this.Page.RegisterStartupScript("",
"<script>alert('Confirm is not correct!');</script>");
}
}
#endregion