MD5加密算法簡(jiǎn)單介紹 在現(xiàn)階段,我們一般認(rèn)為存在兩種加密方式,單向加密和雙向加密。雙向加密是加密算法中最常用的,它將我們可以直接理解的明文數(shù)據(jù)加密為我們不可直接理解的密文數(shù)據(jù),然后,在需要的時(shí)候,可以使用一定的算法將這些加密以后的密文解密為原來(lái)可以理解的明文。雙向加密適合于隱秘通訊,比如,我們?cè)诰W(wǎng)上購(gòu)物的時(shí)候,需要向網(wǎng)站提交信用卡密碼,我們當(dāng)然不希望我們的數(shù)據(jù)直接在網(wǎng)上明文傳送,因?yàn)檫@樣很可能被別的用戶“偷聽(tīng)”,我們希望我們的信用卡密碼是通過(guò)加密以后,再在網(wǎng)絡(luò)傳送,這樣,網(wǎng)站接受到我們的數(shù)據(jù)以后,通過(guò)解密算法就可以得到準(zhǔn)確的信用卡賬號(hào)。 單向加密剛好相反,只能對(duì)數(shù)據(jù)進(jìn)行加密,也就是說(shuō),沒(méi)有辦法對(duì)加密以后的數(shù)據(jù)進(jìn)行解密??赡芪覀兞⒓淳蜁?huì)想,這樣的加密有什么用處?不能解密的加密算法有什么作用呢?在實(shí)際中的一個(gè)應(yīng)用就是數(shù)據(jù)庫(kù)中的用戶信息加密,當(dāng)用戶創(chuàng)建一個(gè)新的賬號(hào)或者密碼,他的信息不是直接保存到數(shù)據(jù)庫(kù),而是經(jīng)過(guò)一次加密以后再保存,這樣,即使這些信息被泄露,也不能立即理解這些信息的真正含義。 MD5就是采用單向加密的加密算法,對(duì)于MD5而言,有兩個(gè)特性是很重要的,第一是任意兩段明文數(shù)據(jù),加密以后的密文不能是相同的;第二是任意一段明文數(shù)據(jù),經(jīng)過(guò)加密以后,其結(jié)果必須永遠(yuǎn)是不變的。前者的意思是不可能有任意兩段明文加密以后得到相同的密文,后者的意思是如果我們加密特定的數(shù)據(jù),得到的密文一定是相同的。 MD5CyptoServiceProvider類是.NET中System.Security.Cryptography名字空間的一個(gè)類,提供專門用于MD5單向數(shù)據(jù)加密的解決方法,也是本文中我們用來(lái)加密數(shù)據(jù)庫(kù)中密碼的類。在真正進(jìn)行數(shù)據(jù)加密之前,我們首先來(lái)了解MD5CyptoServiceProvider類中的主要方法:ComputeHash,它將輸入的明文數(shù)據(jù)數(shù)組使用MD5加密以后輸出加密后的密文數(shù)據(jù)數(shù)組?,F(xiàn)在,我們就來(lái)看一個(gè)具體的實(shí)例: '要加密的明文字符串 Dim strPlainText as String = "Encrypt me!" '用于存放明文字符串的數(shù)組 Dim hashedDataBytes as Byte() Dim encoder as New UTF8Encoding() '建立MD5CryptoService實(shí)例 Dim md5Hasher as New MD5CryptoServiceProvider() '加密運(yùn)算 hashedDataBytes = md5Hasher.ComputeHash(encoder.GetBytes(strPlainText)) 看完以上的具體實(shí)例以后,我們知道,ComputeHash方法只能接受數(shù)組作為加密對(duì)象,輸出的密文也是數(shù)組,因此,在對(duì)字符串加密之前,我們必須首先將這些字符串轉(zhuǎn)化為數(shù)組,這就要用到UTF8Encoding類的GetBytes方法,將字符串轉(zhuǎn)化為數(shù)組,而加密以后的結(jié)果也是使用數(shù)組輸出。 以上我們大致了解了MD5的具體加密實(shí)現(xiàn)方法,下面,我們結(jié)合數(shù)據(jù)庫(kù)來(lái)看看MD5的實(shí)際使用。
使用MD5存儲(chǔ)密碼 在前面的介紹中,我們提到網(wǎng)站往往將用戶的賬號(hào)、密碼等信息使用非加密的方式保存到數(shù)據(jù)庫(kù),比如賬號(hào)使用類型為VarChar的UserCount字段,同樣,密碼也是采用類型為VarChar的Password字段。但是,如果我們打算采用MD5加密方式存儲(chǔ)密碼信息,就必須改變密碼字段PassWord的類型為16為二進(jìn)制方式,這個(gè)其實(shí)我們也不難理解,因?yàn)樵谇懊娴慕榻B中,我們知道加密以后的輸出,是使用二進(jìn)制數(shù)組的,所以,這里必須做相應(yīng)的改變。 當(dāng)用戶注冊(cè)成功,正式建立一個(gè)賬號(hào)的時(shí)候,數(shù)據(jù)庫(kù)中就必須為這個(gè)用戶增加一條記錄。以下的程序代碼實(shí)現(xiàn)了建立一個(gè)賬號(hào)的功能,在頁(yè)面中,程序要求用戶輸入賬號(hào)、密碼等信息,然后,將這些信息作為賬號(hào)信息存入名為UserCount的數(shù)據(jù)表,在這個(gè)表中,用戶密碼是使用MD5加密保存的。下面就是實(shí)現(xiàn)以上頁(yè)面的具體代碼: <%@ Import Namespace="System.Security.Cryptography" %> <%@ Import Namespace="System.Text" %> <%@ Import Namespace="System.Data" %> <%@ Import Namespace="System.Data.SqlClient" %> <Script runat="server" language="VB"> Sub CreateAccount(sender as Object, e as EventArgs) '1. 建立數(shù)據(jù)庫(kù)連接 Const strConnString as String = "connection string" Dim objConn as New SqlConnection(strConnString) '2. 建立Command對(duì)象 Dim strSQL as String = _ "INSERT INTO UserAccount(Username,Password) " & _ "VALUES(@Username, @Password)" Dim objCmd as New SqlCommand(strSQL, objConn) '3. SQL參數(shù) Dim paramUsername as SqlParameter paramUsername= New SqlParameter("@Username", SqlDbType.VarChar, 25) paramUsername.Value = txtUsername.Text objCmd.Parameters.Add(paramUsername) '加密用戶密碼 Dim md5Hasher as New MD5CryptoServiceProvider() Dim hashedBytes as Byte() Dim encoder as New UTF8Encoding() hashedBytes=md5Hasher.ComputeHash(encoder.GetBytes(txtPwd.Text)) Dim paramPwd as SqlParameter paramPwd = New SqlParameter("@Password", SqlDbType.Binary, 16) paramPwd.Value = hashedBytes objCmd.Parameters.Add(paramPwd) '加入數(shù)據(jù)庫(kù) objConn.Open() objCmd.ExecuteNonQuery() objConn.Close() End Sub </script> <Form runat="server"> <h1>建立一個(gè)賬號(hào)</h1> 用戶名:<asp:TextBox runat="server" id="txtUsername" /> <br />密碼: <asp:TextBox runat="server" id="txtPwd" TextMode="Password" /> <p><asp:Button runat="server" Text="建立用戶賬號(hào)" onClick="CreateAccount" /></p> </form> 在以上程序?qū)崿F(xiàn)的頁(yè)面中,“用戶名”和“密碼”輸入框要求用戶輸入自己的賬號(hào)和密碼,用戶輸入自己的信息以后,按“建立用戶賬號(hào)”按鈕,就可以建立一個(gè)賬號(hào)并且存入數(shù)據(jù)庫(kù)。我們同時(shí)需要特別注意,因?yàn)橐陨系某绦蚴褂玫搅薓D5加密和數(shù)據(jù)庫(kù)等功能,所以,在代碼最開(kāi)頭,我們引入了幾個(gè)稍微特別一點(diǎn)的名字空間,這是不可缺少的。 我們可以看到,PassWord字段的信息是二進(jìn)制方式保存的,即使數(shù)據(jù)庫(kù)被人取得,也不可能知道密碼具體是什么意思。當(dāng)然,密碼也就不會(huì)泄露。