摘要:通過使用Rijndael算法對數據庫連接字符串進行加密,增強系統的安全性。首先分析.NET Framework提供的密碼類,然后設計了具體的Rijndael的應用類。管理員設置數據庫連接信息,并用Rijndael加密后,放置于Web.config配置文件中。應用程序從Web.config中取出連接字符串,解密后,用其創建ADO.NET數據庫連接。
關鍵詞:Rijndael;密碼算法;.NET Framework;Web.config
中圖分類號:TP309文獻標識碼:A 文章編號:1009-3044(2008)11-20197-03
1 引言
網上應用系統在實現業務管理的同時,很多系統還實現了銀行SSL電子支付和銀聯網關支付。由于涉及資金,安全性、特別是數據庫的安全越來越重要,用Rijndael算法[1]加密數據庫連接配置參數是保障系統安全的重要手段之一。
2 應用系統的多層結構
基于微軟技術的系統,實現銀聯網關在線支付以及到財務系統的接口,多通過消息中間件MSMQ、網關和終端仿真實現和主業務系統的結合。系統的后臺數據庫是非常重要的,置于最嚴密的保護下。但是Web服務器一般放在防火墻之外,或者內外防火墻之間的隔離區中,比較容易受到外部攻擊。程序連接數據庫需要數據庫服務器的地址、帳號和密碼、數據庫實例名稱等,這些信息往往以數據庫連接字符串的形式置于Web應用的配置文件Web.config中。一來可以集中存放數據庫連接配置,二來方便管理員修改,使得程序員和數據庫的管理的工作分開。雖然Windows和.NET提供了保護手段,能夠防止Web.config被客戶端閱讀和下載,但是如果IIS存在某些漏洞,或者當操作系統本身被攻破,Web.config中的數據庫連接字符串可能為黑客進一步攻擊數據庫服務器提供重要信息。
用Rijndael加密Web.config中的數據庫連接字符串,攻擊者即使獲得該文件,也無法得到數據庫的信息,從而增強系統的安全性。
3 Rijndael算法
3.1 Rijndael算法簡介
美國政府于1997 年開始公開征集新的數據加密標準算法AES (A dvanced Encryp t ion Stan2dard, 簡稱AES) , 以取代DES。經過三輪篩選, 最終選中比利時密碼學家Joan Daem en 和V incen tR ijm en 提出的一種密碼算法Rijndael作為AES。我國也采用AES作為商業密碼算法。
Rijndael 算法之所以能夠最終被選為AES的原因是其安全、高效、實用和靈活[2]。
3.2 .NET Framework的密碼類
.NET Framework支持多種密碼算法和單向散列算法,相關的類位于System.Security.Cryptography命名空間[3]。
針對對稱密碼算法,.NET Framework提供了抽象類SymmetricAlgorithm,其中定義了加密模式,密鑰Key,加密算法的初始向量IV(用于CBC等反饋加密模式)等屬性。針對Rijndael算法,.NET定義了Rijndael的抽象類:
public abstract class Rijndael: SymmetricAlgorithm;
由于Rijndael不象DES或者三蟲DES算法那樣存在弱密鑰,所以不存在DES的IsWeakKey方法。
Rijndael算法的托管代碼實現類RijndaelManaged繼承自Rijndael,用以創建類的實例[5]。
public sealed class RijndaelManaged: Rijndael;
4 網上應用系統的加密類
由于基于反饋的加密模式比每塊單獨加密(既ECB模式)提供了更好的抗分析能力,我們采用引入反饋的CBC(Cipher Block Chaining)加密模式[4]。除了需要密鑰之外,還需要和塊大小相同的偏移向量IV(initialization vector)。
4.1 產生密鑰Key和偏移向量IV
Rijndael屬于對稱密碼算法,其加密密鑰和解密密鑰相同,有三種迷鑰長度128,192,256位,一般情況下128位已經足夠。我們用RijndaelManaged的GenerateKey()和GenerateIV()方法產生密鑰然后保存到字符數組中,供后續使用[5],如以下的代碼所示:
byte[] key;
byte[] IV;
//Create a new key and initialization vector.
myRijndael.GenerateKey();
myRijndael.GenerateIV();
//Get the key and IV.
key = myRijndael.Key;
IV = myRijndael.IV;
4.2 設計加密類
定義類My_Rijndael,該類的構造方法指定了加密模式、密鑰和初始向量,并包含加密和解密方法。
sealed class My_Rijndael//該類不可繼承防止繼承后被修改
{
static RijndaelManaged My_RijndaelManaged;
public My_Rijndael()
{
My_RijndaelManaged = new RijndaelManaged();
//加密模式
My_RijndaelManaged.Mode = CipherMode.CBC;
//建立加密對象的密鑰和偏移量,事先由GenerateKey和GenerateIV產生并且保存
My_RijndaelManaged.Key = new byte[16] { 233, 188, 176, 143, 41, 59, 188, 236, 195, 23, 201, 111, 242, 198, 188, 67 };
My_RijndaelManaged.IV = new byte[16] { 18, 176, 75, 251, 41, 59, 188, 5, 195, 32, 177, 136, 242, 198, 42, 67 };
}
public string Encrypt(string pToEncrypt)
{
//把字符串放到byte數組中
byte[] inputByteArray = Encoding.Default.GetBytes(pToEncrypt);
MemoryStream ms = new MemoryStream();
//定義一個流連接數據流和加密變換
CryptoStream cs = new CryptoStream(ms, My_RijndaelManaged.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
StringBuilder ret = new StringBuilder();
foreach (byte b in ms.ToArray())
{
ret.AppendFormat(\"{0:X2}\", b);
}
ret.ToString();
return ret.ToString();
}
解密方法和加密方法類似,在此省略。
5 加密類的使用
5.1 加密連接字符串
用上述的My_Rijndael類,編寫了一個加密程序,運行如圖2所示:
加密程序關鍵代碼如下:
//創建My_Rijndael類的實例
My_Rijndael crypt = new My_Rijndael();
//用類My_Rijndael的Encrypt方法加密數據庫連接字符串
textBox_encrypt.Text=crypt.Encrypt(textBox_plaintext.Text.Trim() );
在Web應用程序的配置文件Web.config中,增加結點ConnectionString,將其結點的值賦為連接字符串加密后的密文。
<appSettings>
<add key=\"ConnectionString\" value=\" 5C3F578E4A5048ABDAB60D33451CCF8AD1BDA4E74352463E32492766385AFBC0D68122 E62C99FBF56B177660B90BAE7C7C3861CF76E0D4D8C20632E83458D397E37B86300FA5EDB7A1B114C3C98C6918 \"/>
</appSettings>
5.2 修改Web.config的方法
當數據庫連接參數改變時,配置文件中的加密串也要相應修改。修改Web.config有多種方法:可以手工修改Web.config文件, 也可以編寫程序修改Web.config,例如利用System.Web.Configuration命名空間中的WebConfigurationManager類。
對于.NET2.0,VS.NET2005提供了Web Site Administration Tool,可以方便的更改Web.config中的配置,我們采用的正是這種方法。需要注意的是,更改Web.config后,應用程序會重新啟動,所有的Session也將丟失。
5.3 解密連接字符串
應用程序從配置文件中取出數據庫連接字符串的密文[6],然后進行解密:
String temp_constring, constring;
temp_constring=System.Configuration.ConfigurationSettings.AppSettings[\"ConnectionString \"];
My_Rijndael crypt = new My_Rijndael ();
Constring = crypt.Decrypt(temp_constring);
根據解密后的數據庫連接字符串,創建ADO.NET數據庫連接
System.Data.SqlClient.SqlConnection con1 = new System.Data.SqlClient.SqlConnection();
con1.ConnectionString= Constring;
6 結論
用Rijndae加密數據庫連接字符串,增強了Web.config的保密程度。在網上應用系統的實際工作中,在Web服務器上只部署編譯后的.NET程序集(Assembly dll),而不發布aspx和cs源文件,并且用混淆器Aspose Obfuscator.NET v1.4對編譯后的.NET程序集進行處理,使其難以被反編譯。通過采取這些措施,大大增強了系統的整體安全性[7]。
參考文獻:
[1] 張煥國, 覃中平. 高級數據加密標準的研究[J]. 計算機工程與科學, 2001,(5):91-94.
[2] 胡向東,魏琴芳.應用密碼學教程[M].電子工業出版社,2005:63-68.
[3] 吉尚戎. .NET框架程序員參考手冊·常規操作篇[M]. 國防工業出版社,2001,(10):10-13
[4] RijndaelManaged Class[EB/OL].http://msdn.microsoft.com/library/default.asp?url=/ library/en-us/cpref/html/frlrfsystemsecuritycryptographytripledescryptoserviceproviderclasstopic.asp.
[5] Wenbo Mao. Modern Cryptograpy:Theory and Practice[M]. Pearson Education,2004:155-163.
[6] WadeTrappe. Introduction to Cryptography with Coding Theory[M].Washington:Pearson Education,2003:82-84.
[7] 周杰韓,吳波.微軟密碼類設計與應用編程[J].電腦編程技巧與維護,2000,(3):88-92.
注:本文中所涉及到的圖表、注解、公式等內容請以PDF格式閱讀原文