作者:陳俊傑 / 臺灣大學計算機及資訊網路中心教學研究組幹事
根據《蘋果日報》於2013年9月12日所刊出「中國程式秒殺台鐵50萬票」的報導,分析網路黃牛的犯罪手法,指出嫌犯是利用所買來的電腦程式在8秒內訂走50萬張車票,而台鐵亦表示會將驗證碼由四碼改為四至六位數浮動碼,以增加程式辯識的困難度,防止有人利用程式大量訂票[1]。或許成效有限,但仍能提供一定的防護能力,因此,本文將介紹如何撰寫簡易的驗證碼程式,讓使用者也能自主學習如何提升網站的安全性。
簡介
何謂「驗證碼」?根據維基百科的說明,它是用來區分使用者是電腦或人的驗證程式,由電腦會自動產生問題,然後再讓使用者回答,但必須只有人類才能解答,所以能夠解答的使用者就可以被認為是人類[2]。
因此,本文所撰寫的簡易驗證碼程式,其功能設計如下:
1. 驗證碼的長度必須是浮動而非固定,如6~8字元。
2. 主要由大寫英文、小寫英文、數字所組合,文字或數字可以重複,但每種組合至少須含有2個字元,如AAbb00。
3. 具有干擾光學字元識別(OCR)辨識出圖片文字或數字的能力。
4. 驗證碼的有效時間為60秒。
5. 只要圖片重新載入,驗證碼即須重新產生。
6. 僅接受POST傳遞的資料,且圖片路徑不能有任何提示和改變。
驗證碼流程架構
![](001/Upload/354/ckfile/7270e66d-5884-45ff-a0c4-79a741a6efcd.jpg)
圖一 驗證碼流程及模組功能圖
作業環境
1. 作業系統:Windows 7 Service Pack 1
2. 網頁伺服器:IIS 7.5
3. 網頁語法:C#、VB.Net
4. 開發工具:Visual Studio 2010 Professional
編輯Views / Shared版面配置頁(C#、VB.Net)
1. 新增「_LayoutCaptcha」檔案,如圖二、圖三:
![](001/Upload/354/ckfile/588504ca-3bcf-4312-ae3d-0604b67225c8.jpg)
圖二 C#版本
![](001/Upload/354/ckfile/864ce052-f50e-447c-8122-c5f85ba9aef3.jpg)
圖三 VB版本
2. head標籤內容,如圖四:
![](001/Upload/354/ckfile/f2b31183-ccde-46e9-b302-51c267070f7a.jpg)
圖四
3. body標籤內容,如圖五:
![](001/Upload/354/ckfile/214a5062-bbea-43d9-b1e1-1532b3171177.jpg)
圖五
補充:使用Url.Action語法的效果,如圖六:
![](001/Upload/354/ckfile/ceeaad68-0214-48e0-baf1-b9847f023c50.jpg)
圖六 從Chrome的檢視原始碼
編輯Models模組(C#、VB.Net)
1. 新增CaptchaHelper(Class類別)檔案,如圖七、圖八:
![](001/Upload/354/ckfile/6705a453-96ff-4498-b855-61294fea41f3.jpg)
圖七 C#版本
![](001/Upload/354/ckfile/c9983e2f-90e6-4e04-a145-612243eb183c.jpg)
圖八 VB.Net版本
2. 匯入指定的命令空間和類型,讓程式可直接參考,如圖九、圖十:
![](001/Upload/354/ckfile/7002a892-0643-4cd7-9cb2-32bc01193e4e.jpg)
圖九 C#版本
![](001/Upload/354/ckfile/39744221-f699-4298-a931-c74f1d60a24b.jpg)
圖十 VB.Net版本
補充:因本範例需要「判斷字串是否為日期格式」,僅C#版本需要自行建立判斷功能,其內容如圖十一:
![](001/Upload/354/ckfile/9769ed51-a84b-4bb5-8f8e-d2bb1ab311d6.jpg)
圖十一
3. 建立「判斷驗證結果」功能,如圖十二、圖十三:
![](001/Upload/354/ckfile/76dfbc09-191d-462e-a216-abf85a874f9c.jpg)
圖十二 C#版本
![](001/Upload/354/ckfile/c8e6245d-5049-4550-adca-9394ca80ee44.jpg)
圖十三 VB版本
4. 建立「產生驗證碼小幫手」功能,將原始碼各分二個部分解說,如圖十四~圖十七:
![](001/Upload/354/ckfile/37a11e70-01cf-4d07-b37d-31647c9b5bdd.jpg)
圖十四 C#版本(第一部分)
![](001/Upload/354/ckfile/93ca657e-f75a-4875-b5b6-bdd68d8ff6ac.jpg)
圖十五 C#版本(第二部分)
![](001/Upload/354/ckfile/4c9728b0-3e9e-499c-a0e1-e3e984550f00.jpg)
圖十六 VB.Net版本(第一部分)
![](001/Upload/354/ckfile/2e9a2ad0-2a90-45e4-87d9-bad078412fed.jpg)
圖十七 VB.Net版本(第二部分)
5. 建立「將驗證碼轉成圖片小幫手」功能,將原始碼各分三個部分解說,如圖十八~圖二十三:
![](001/Upload/354/ckfile/db2e32f0-e3af-483d-b8f9-b343f5726da6.jpg)
圖十八 C#版本(第一部分)
![](001/Upload/354/ckfile/77c13c1d-f408-431a-a251-05547376f8d6.jpg)
圖十九 C#版本(第二部分)
![](001/Upload/354/ckfile/eb264270-c57d-4b73-986c-d996aedb804e.jpg)
圖二十 C#版本(第三部分)
![](001/Upload/354/ckfile/f4ec86bc-dae9-4558-8ca6-c8890a40a59b.jpg)
圖二十一 VB.Net版本(第一部分)
![](001/Upload/354/ckfile/80a12260-7f4d-4c69-9cbf-34d1b8135628.jpg)
圖二十二 VB.Net版本(第二部分)
![](001/Upload/354/ckfile/51aebbf1-5120-4707-9bc2-4daf9c23e462.jpg)
圖二十三 VB.Net版本(第三部分)
編輯Controller控制器(C#、VB.Net)
1. 新增Captcha(Controller控制器)檔案,如圖二十四、圖二十五:
![](001/Upload/354/ckfile/ff281f27-dc6f-4da1-977f-1555fbe432a6.jpg)
圖二十四 C#版本
![](001/Upload/354/ckfile/96e6f1c0-6a47-470f-be2b-84beb721e4c7.jpg)
圖二十五 VB.Net版本
2. 編輯Captcha(Controller控制器)檔案內容,如圖二十六、圖二十七:
![](001/Upload/354/ckfile/8e141311-d556-48ab-a37f-4540fa35e2ed.jpg)
圖二十六 C#版本
![](001/Upload/354/ckfile/86d5a039-16ef-4ee0-9c95-aed2efe30c52.jpg)
圖二十七 VB.Net版本
補充:僅C#版本需要自行設定匯入Models模組所設定的空間命名及其類型,其內容如圖二十八:
![](001/Upload/354/ckfile/ce333749-e4fc-4baf-93e7-fcbdfa6afd2a.jpg)
圖二十八 C#版本
編輯Views / Captcha檢視頁面(C#、VB.Net)
1. 新增Index(首頁)及Result(驗證結果)的檢視,如圖二十九、圖三十:
![](001/Upload/354/ckfile/b2fac533-1ead-4624-8468-3be9a559408f.jpg)
圖二十九 C#版本
![](001/Upload/354/ckfile/704a40d2-1f58-4b9f-b4a9-154ad4ea310e.jpg)
圖三十 VB.Net版本
2. 加入Index(首頁)檢視時的設定,如圖三十一、圖三十二:
![](001/Upload/354/ckfile/3140fd33-3fd3-480d-b603-6c47bee16658.jpg)
圖三十一 C#版本
![](001/Upload/354/ckfile/e9fb4527-8fee-4f76-83db-8a59b401cd56.jpg)
圖三十二 VB.Net版本
3. 編輯Index(首頁)檢視的內容,如圖三十三、圖三十四:
![](001/Upload/354/ckfile/a7ac7323-60a7-4eaa-b8f2-09ea7cd89460.jpg)
圖三十三 C#版本
![](001/Upload/354/ckfile/592993d2-3268-44c4-b98e-828047be443a.jpg)
圖三十四 VB.Net版本
4. 加入Result(驗證結果頁)檢視時的設定,如圖三十五、圖三十六:
![](001/Upload/354/ckfile/8b0c93ed-9f38-409b-8e25-7377ef0257be.jpg)
圖三十五 C#版本
![](001/Upload/354/ckfile/e2a525cd-970d-4a8c-94a3-b1edfd532bed.jpg)
圖三十六 VB.Net版本
5. 編輯Result(驗證結果頁)檢視的內容,如圖三十七、圖三十八:
![](001/Upload/354/ckfile/06349e63-572b-4b67-9e17-f41b5cc7fc7a.jpg)
圖三十七 C#版本
![](001/Upload/354/ckfile/ac937a11-9c69-4692-802f-9ce0f0f26a96.jpg)
圖三十八 VB.Net版本
預覽結果
1. 在Chrome瀏覽器上的預覽,如圖三十九、圖四十:
![](001/Upload/354/ckfile/de035c55-29cf-4299-a610-2c7f7b0a1d44.jpg)
圖三十九 C#版本
![](001/Upload/354/ckfile/6edb6722-a206-41d0-bdce-4135a00114e3.jpg)
圖四十 VB.Net版本
測試是否具有干擾OCR功能
1. 產生未加入干擾OCR功能的圖片(圖四十一),及加入干擾OCR功能的圖片(如圖四十二):
![](001/Upload/354/ckfile/8c95d26a-190b-42a0-99c3-371b7b8600c7.jpg)
圖四十一 「未加入」干擾OCR功能
![](001/Upload/354/ckfile/9ed4f742-966b-47fd-b419-cc876d84f14e.jpg)
圖四十二 「加入」干擾OCR功能
2. 以「Copyfish Fresh OCR Software」套件作測試[3],其比較結果如圖四十三、圖四十四:
![](001/Upload/354/ckfile/d5859fbf-f56e-41c7-94ca-a32039c4ba54.jpg)
圖四十三 「未加入」干擾OCR功能
![](001/Upload/354/ckfile/99c716a5-e839-474f-b438-e6ab6000020b.jpg)
圖四十四 「加入」干擾OCR功能
3. 以「Google Drive」作測試[4],其比較結果如圖四十五~圖四十七:
![](001/Upload/354/ckfile/815fd64e-f95c-4093-9438-06e3f47e62ef.jpg)
圖四十五
![](001/Upload/354/ckfile/a682b49b-6083-461b-890c-c24fcb08a881.jpg)
圖四十六 「未加入」干擾OCR功能
![](001/Upload/354/ckfile/d1ce2933-d609-48bb-9fd0-1eb0475d7c99.jpg)
圖四十七 「加入」干擾OCR功能
結論
經實驗確認,本範例確能干擾OCR功能,而無法正確取得圖片中的文字,但仍僅適合作為提高網站被破解的困難度,或是作為學習撰寫驗證碼程式入門參考,建議勿作為唯一的網站保護工具。
因此,根據《PanSci泛科學》的文章,雖然驗證碼的發展已有一定時間,但實際上亦發現許多破解的方法。像是Google就所研發的圖像識別演算法,就能辨認網站的驗證碼,而且準確率高達96%,並表示若只靠驗證碼來保護網站是不夠的[5]。
參考資料
[1] 林志青、李姿慧(2013年09月12日)。中國程式 秒殺台鐵50萬票。蘋果日報。線上檢索日期:2016年11月02日。網址:
http://www.appledaily.com.tw/appledaily/article/headline/20130912/35289113/中國程式秒殺台鐵50萬票
[2] 驗證碼。維基百科。檢上檢索日期:2016年11月02日。網址:
https://zh.wikipedia.org/wiki/%E9%AA%8C%E8%AF%81%E7%A0%81
[3] esor huang(異塵行者)(2015年10月22日)。 Copyfish 驚奇 Chrome 套件複製圖片影片內中文字!電腦玩物。檢上檢索日期:2016年11月07日。網址:
http://www.playpcesor.com/2015/10/copyfish-chrome.html
[4] esor huang(異塵行者)(2015年05月08日)。 Google Drive 超工作術:16招雲端硬碟變最強辦公桌。電腦玩物。檢上檢索日期:2016年11月07日。網址:
http://www.playpcesor.com/2015/05/google-drive-16.html
[5] afore(2015年07月10日)。要證明自己是人類很不容易 ── Google意外破解驗證碼檢核機制。PanSci泛科學。線上檢索日期:2016年11月07日。網址:
http://pansci.asia/archives/81040