一、驗證碼
對於一個預防攻擊的web表單來講,驗證碼通常是一個常見的措施。因為如果對於一些public地區的頁面內容來講,譬如一個登入表單,如果沒有必要的安全措施,很可能遭到類比登入的暴力破解攻擊,要麼輕易獲得特定賬戶的登入資訊,要麼給伺服器增加了大量的負荷,影響正常的服務。解決的辦法,一般就是在登入前給出一個隨機的資訊(驗證碼),顯示在頁面上,讓使用者填寫,以確保使用者是通過web頁面來進行正常的登入,對於非法的非web途徑登入者會看不到這個驗證碼從而拒絕其登入。雖然這樣,往往很多攻擊者會截獲登入web頁,從而也搜尋出驗證碼,這樣,驗證保護措施也失去意義,一般情況下,我們可以通過將驗證資訊作為映像資訊顯示在web上,這樣就既可以不阻礙合法使用者登入,又使非法攻擊者無法通過html搜尋獲得驗證資訊。這大抵上就是驗證碼的用途和意義了。
二、ASP.Net的驗證碼實現
一般傳統的驗證碼映像一般採用一些CGI、ISAPI程式加上一些加密代碼來動態產生映像,ASP大多採用COM組件實現,相當辛苦。
ASP.Net中欲實現動態驗證碼卻相當容易,筆者大致的思路:
1、 了安全起見,一般存在於CGI程式的url中的驗證碼加密串最好不要出現在html表單中,而是採用session變數儲存,這樣驗證碼的校正會很容易。
2、 採用一個單獨的aspx頁面專門產生動態程式,要顯示的圖形驗證碼資訊存在於session中,而一個系統中有可能存在多個表單,為滿足整個系統要求可以在aspx後加一個確定的session key的名稱,例如
<img src=”http://xxxx/Genimg/viewImg.aspx?sessionKeyName=abc”> 此處的abc就是登入頁在第一次輸出表單給用戶端自動產生一個隨機字串儲存在session中的key名稱,在伺服器端指令碼中可以通過session(“abc”)獲得產生的字串(驗證碼)到底是多少,通過和使用者在表單的驗證碼輸入框中輸入的內容比較來確定使用者是否通過正常的ie瀏覽器來訪問表單。
3、 在表單的第一次顯示(get方法)時,產生一個隨機數字串,存入session(“abc”)中,同時將abc作為sessionKeyName的值加入到驗證碼圖形顯示產生程式viewImg.aspx的url串中。
4、 ViewImg.aspx分析sessionKeyName,擷取session(“abc”)的具體值,利用GDI+產生記憶體配置圖像,然後修改http header,按照content-type=images/png的格式輸出二進位流,這樣客戶的瀏覽器會顯示出一幅映像,映像表達的內容就是驗證碼。
5、 當使用者填入驗證碼後,提交到表單驗證程式,首先考察其中的驗證碼輸入欄位,發現不匹配session(“abc”)馬上拒絕,甚至可以累計失敗登入次數,乃至拒絕此IP串連,保護系統;匹配session中的儲存值,可以進行進一步的其他處理(譬如登入處理,文章發表等),當然也注意銷毀此session變數(如果以後不需要)。
6、 不同的表單,可以分配不同的session變數名,這樣一個ViewImg.aspx可以為系統多個表單服務。
三、執行個體解說
重點列出viewImg.aspx吧,具體看清單:
Imports System.IO
Public Class viewImg
Inherits System.Web.UI.Page
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim img As Bitmap
Dim gdiobj As Graphics
Dim ms As MemoryStream ''''--記憶體流,存放動態圖形記憶體印象
Dim vfycode As String ''''--驗證碼
Dim SessionKeyname As String
If (Request("SessionKeyName") <> "") Then
SessionKeyname = Request("SessionKeyName")
If (Session(SessionKeyname) <> "") Then
vfycode = Session(SessionKeyname)
Else
vfycode = ""
End If
img = New Bitmap(32, 16) ''''--這個寬高可以根據需要確定
gdiobj = Graphics.FromImage(img)
gdiobj.DrawString(vfycode, (New Font("Arial", 9)), (New SolidBrush(Color.Black)), 0, 0)
ms = New MemoryStream()
img.Save(ms, System.Drawing.Imaging.ImageFormat.Png) ''''--選擇透明格式
Response.ClearContent() ''''--原本是準備輸出html流,現在輸出圖信資料,所以要修改http頭
Response.ContentType = "image/png"
Response.BinaryWrite(ms.ToArray())
Else
End If
Response.End() ''''--這個最好帶上
End Sub
End Class
小小小程式員 2007-04-03 11:27 發表評論
文章來源:http://www.cnblogs.com/greateast/archive/2007/04/03/697982.html