ConnectionString中的資料庫登入密碼加密
- 連線到資料庫;(如果你通常都是採用Windows整合驗證,那麼這篇文章可能你不需要看下去了)假設你採用的是SA + 密碼的驗證方式;
- 新增新資料來源;VS.NET在這裡提醒我們,連線串裡面包含了敏感資訊;
- 把連線字串儲存到程式的配置檔案裡,便於使用和維護;
<?xmlversion="1.0"encoding="utf-8" ?>
<configuration>
<configSections>
</configSections
<connectionStrings>
<addname="Test.Properties.Settings.TestConnectionString"
connectionString="Data Source=.;Initial Catalog=TEST_ERP;Integrated Security=False;uid=sa;password=shiny"
providerName="System.Data.SqlClient"/>
</connectionStrings>
</
生成EXE,在輸出目錄下面會產生一個Text.exe.config檔案,剛才App.config裡面的內容複製到了這個檔案,這個是釋出的時候需要安裝到使用者程式路徑的,由於是文字檔案,我們可以很輕鬆的根據使用者的實際環境修改裡面的連線設定。但是,sa的密碼儲存在裡面怎麼說也是很令人忐忑的事情。
一個很自然的思路,我們可以把這個密碼字串經過加密再儲存,要用的時候再解密,以下是我具體的做法。
我採用的是DES的加密方式,也許你喜歡其他的加密演算法,反正只要有對應的解密演算法,都沒問題。
這個是我在網上找的加密工具類,公開了加密和解密的方法。
1class CryptClass
3 //預設金鑰向量 4privatestaticbyte[] Keys ={ 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
5 publicstaticstring EncryptKey ="12345678";
6
7 ///<summary> 8 /// DES加密字串
9 ///</summary>10 ///<param name="encryptString">待加密的字串</param>11 ///<param name="encryptKey">加密金鑰,要求為8位</param>12 ///<returns>加密成功返回加密後的字串,失敗返回源串</returns>
13publicstaticstring EncryptDES(string encryptString, string encryptKey)
14 {
15 try16 {
17 byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8));
18 byte[] rgbIV = Keys;
19 byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
20 DESCryptoServiceProvider dCSP =new DESCryptoServiceProvider();
21 MemoryStream mStream =new MemoryStream();
22 CryptoStream cStream =new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
23 cStream.Write(inputByteArray, 0, inputByteArray.Length);
24 cStream.FlushFinalBlock();
25 return Convert.ToBase64String(mStream.ToArray());
26 }27 catch28 {
29 return encryptString;
30 }31 }32
33 ///<summary>34 /// DES解密字串
35 ///</summary>36 ///<param name="decryptString">待解密的字串</param>37 ///<param name="decryptKey">解密金鑰,要求為8位,和加密金鑰相同</param>38 ///<returns>解密成功返回解密後的字串,失敗返源串</returns>
39publicstaticstring DecryptDES(string decryptString, string decryptKey)
40 {
41 if (decryptString =="")
42 return"";
43 try44 {
45 byte[] rgbKey = Encoding.UTF8.GetBytes(decryptKey);
46 byte[] rgbIV = Keys;
47 byte[] inputByteArray = Convert.FromBase64String(decryptString);
48 DESCryptoServiceProvider DCSP =new DESCryptoServiceProvider();
49 MemoryStream mStream =new MemoryStream();
50 CryptoStream cStream =new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
51 cStream.Write(inputByteArray, 0, inputByteArray.Length);
52 cStream.FlushFinalBlock();
53 return Encoding.UTF8.GetString(mStream.ToArray());
54 }55 catch56 {
57 return"";
58 }59 }60 }
用你的密碼,和自己選擇好的金鑰(記住要8位字串)作為引數,呼叫一下上面的EncryptDES,得到加密後的密碼字串,用它把Test.exe.config裡面的密碼替換,現在我的config檔案裡面是:
connectionString="Data Source=.;Initial Catalog=TEST_ERP;Integrated Security=False;uid=sa;
password="gcEHA/213uBLSOruspbHyQ==""
[注意:不要修改App.config裡面的內容,這樣的話,你在設計期開發環境裡面的資料來源就連線不上了,而且,要留意別讓生成程式的時候VS把你的修改沖掉了,只需要把App.config的屬性"複製到輸出目錄" 設定為不復制就可以了]
下面我們來看看怎麼在執行的時候解密出原來的密碼:
如果你總是自己用程式碼建立SQLConnection,那麼只需要在建立前把ConnectionString裡面的password部分解密就好了,利用上面加密類的解密函式。
問題是我們都是很普遍的使用VS幫我們建立好的強型別的Dataset,和強型別的DataAdapter。而這些DataAdapter已經包含了建立SQLConnection的程式碼,他們通過讀取程式配置的方式獲得連線串,方式如下:
this._connection.ConnectionString = global::Test.Properties.Settings.Default.TestConnectionString;//這個屬性是隻讀的
程式配置是在程式第一次需要讀取的時候載入的,我們需要改動它的預設行為,加入解密的操作。
1.展開專案樹下面的Properties資料夾,雙擊Settings.settings節點;
2.在顯示的窗口裡麵點擊上面的檢視程式碼,此時將會在你的專案下產生一個Settings.cs原始檔;
3.修改裡面的程式碼如下:
using Utilities;
using System.Data.SqlClient;
using System.Data.OleDb;
internalsealedpartialclass Settings {
public Settings() {
//// To add event handlers for saving and changing settings, uncomment the lines below:
//
// this.SettingChanging += this.SettingChangingEventHandler;
//
this.SettingsLoaded +=this.SettingsLoadedEventHandler;
//
}
privatevoid SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) {
// Add code to handle the SettingChangingEvent event here.
}
privatevoid SettingsLoadedEventHandler(object sender,System.Configuration.SettingsLoadedEventArgs e) {
// Add code to handle the SettingsSaving event here.
SqlConnectionStringBuilder ConnSb =new SqlConnectionStringBuilder();
string s1;
ConnSb.ConnectionString =this["TestConnectionString"].ToString();
ConnSb.Password = CryptClass.DecryptDES(ConnSb.Password, CryptClass.EncryptKey);
s1 = ConnSb.ConnectionString;
SetConstr(s1);
}
publicvoid SetConstr(string connstr1)
{
this["TestConnectionString"] = connstr1;
}
}
}
上面程式碼,public了SetConstr方法,以便於在程式的其他模組還可以有機會動態修改連線串。