[技術探討] 透過WCF實現Challenge & Response架構之 身分驗證 (I)

WCFverification

透過WCF實現Challenge & Response架構之 身分驗證 (I)

身分驗證是軟體開發,特別是網站實務中不可或缺的技術,牽涉的層面包含帳號驗證機制、密碼加解密技術等。以過去在C# .NET上的開發經驗,一般經常會使用Windows驗證或表單驗證,來實現帳號驗證機制。

近年經由技術演變,軟體開發平台也愈趨多元,尤其在手持裝置上開發技術的蓬勃發展,各式各樣的應用程式出現在手持裝置上,因此帳號驗證技術的需求也愈來越不可輕忽,因此面對不同開發平台的用戶端(如iOS, Android, Windows Phone),希望這些用戶端的帳號資訊能整合在一個資料庫中,勢必在管理上能夠省去不少麻煩。

但我們更需要關切的議題是,如何確保傳輸過程的安全性?

過去,我們做了一個表單驗證,使用者填入帳號、密碼,按下登入按鈕後,便將使用者的帳號密碼資訊送到Server端,由Server拿帳號密碼去比對,在這當中,未經過處理的資料在封包傳輸過程完全透明化,只要有心人刻意攔截封包,帳號密碼資訊即可一覽無遺,縱使我們後來會以加密技術對密碼進行加密,但除非是使用了不可逆之加密演算法(如MD5),不然被破解也只是時間上的問題而已。

回歸正題,為了避免發上以上問題,我們想出八字訣:「不傳密碼,以絕後患。」乍聽之下也許有點玄。不傳密碼到Server端如何比對密碼?原來有個辦法也許可以實現這個不可能的任務。

答案就是Challenge – Response機制。如同字面意思,挑戰與回應,意即是Client端收到Server的「挑戰」,並且做出正確「回應」,以證明該使用者身分無誤,然後才能做登入後的動作。

Challenge

那Server端該拿什麼來挑戰?什麼樣的挑戰才能讓Client端證明是該使用者?

前面我們提到了,不會在網路上傳遞密碼資訊。但不代表密碼不會用到,畢竟使用者的個人密碼還是我們用來做使用者身分認證的唯一依據。不過在使用密碼的過程中,會動一點手腳-結合加解密技術(註1)。

於是開始進行身分驗證的第一步,首先Client告訴Server端目前請求登入的身分為何,Server端在此將提供了一個WCF服務,Client端在呼叫時帶入該使用者帳號及其他次要參數(如裝置id)(註2),Server端收到登入請求時,便會到資料庫取得該使用者帳號所對應之密碼,並將密碼以一組字串進行加密,加密後會產生一組新的字串,這組字串也就是Server端對Client端的挑戰,或一般稱之為”挑戰字串(Challenge String)”,此部分提供之WCF方法示意如下:

 

public string GetChallengeStr(使用者帳號, 裝置id)                         

Response

Client端得到了該Challenge字串,等同收下了挑戰,於是下一步要做的就是,將這組雜亂無章毫無意義的字串進行解密,若能解的出來,表示挑戰成功,使用者可順利登入。

到這個地方,想必多少已經知道,該拿什麼來解密了,就是要求使用者登入時,所輸入之密碼。只要拿這組密碼去對Challenge字串做解密,便能得知使用者輸入的密碼正不正確。同時驗證完後也就不再需要密碼,直到下次登入。

到目前為止,我們已經成功的驗證使用者密碼正確性,其中完全不需要傳遞密碼。不過事情可還沒結束,因為通過驗證的地點是在Client端,此時Server端尚且完全不知情!換句話說目前我們只是在Client端自High而已,除非Server與Client的唯一話題只有帳號驗證…。

 

Token

為了將這個登入的消息告訴Server,我們準備將解密Challenge String所還原得到的一組字串傳給Server作為證明。同時還得加入一個參數,作為本次登入之識別字串(在此稱作Token)。

這個Token,將在後續的動作中扮演重要的角色。因為自從登入之後,便不再傳遞任何驗證相關資訊,於是我們唯一能依靠的,就是這組Token字串。於是我們開始進行這項任務,此部分提供之WCF方法示意如下:

 

public string SetToken(使用者帳號, 裝置id, 解密後的Challenge String, Token)                 

這樣也許就完成了,但疑神疑鬼的我們,還是擔心就這樣讓Token赤裸裸的傳到Server端,中間會出個甚麼差錯,於是再度拿出傢伙,再來對Token以及解密後的Challenge String進行加密(作為回應字串),而加密用的KEY,就使用Server與Client共同訂好的字串來加密。如此到了Server端也能順利地解開並分析內容。因此調整後之WCF方法示意如下:

public string SetToken(使用者帳號, 裝置id, 加密後回應字串, 加密後Token)                      

Will be continue…

如此看起來,整個登入流程算是串連起來了,Client與Server後續只要拿Token做身分比對即可。 在下一篇文章中,會開始針對Challenge & Response進行實作,並實現在不同平台上也能完成此一架構。

 

註1:本篇所使用的加解密技術為AES加解密,簡單的說就是使用一組KEY字串與自訂定義好之IV(向量偏移量),針對資料進行加密或解密之方式。如加密後得到之亂數字串,使用相同之KEY與IV進行解密,即可得到原始資料。

註2:裝置id實現多個裝置登入之設計,即單一帳號可以有不同的Login Session。如規定單一帳號同時只能在一個裝置上做登入,則可省略此參數。


發佈留言

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料