最近因為 project 的關係,接觸了一些身分認證的皮毛,感覺還蠻有趣的,特此紀錄一下。
從古到今,人類的生活充斥著身分認證的問題。山頂洞人要認你外型,確認你是人的形狀才讓你進山洞(我亂猜的...);戰國時代,出現兵符以作為傳令或調兵認證之用,此兵符認證碼由兩半銅、玉、木或石板,需由兩半兵符契合確認命令才能申效,也就是「符合」的由來 (詳見《史記•魏公子列傳》);直到隋唐,兵符逐漸演變為魚符,上面刻有官員姓名、官位等,漸漸具備身份証之功用 (詳見《新唐書•車服》);在西方,以色列人寄居埃及的時代,天使藉由門框上是否塗有羔羊的血,來認證該戶人家的長子是否要殺害 (Exodus 12);新約時代,由於耶穌受人們認證的方式出現分歧,導致有些人將耶穌認證為預言中的彌賽亞,有些人則將耶穌認證為來亂的異端,也因為這一認證的錯亂,引發了近兩千年來的諸多戰爭與傷亡,精確認證的重要性由此可見一番。近年來,則由於個人主義抬頭,導致私有財產暴增,生活中隨處可見認證的影子:要證明你是這間房子的主人?請拿出鑰匙來;要證明你有資格看這場電影?請拿出電影票;要證明這是你的 e-mail 信箱?請輸入你的帳密。諸如此類族繁不及備載,少了身分認證機制,你的就是我的,全家就是你家,這是禮運大同篇共產主義社會才會出現的場景。
身分認證發展至今,大致可以歸類為幾大類 [1]:1. passwords: 記憶性的認證,回答問題答對就過關,如密碼;2. tokens: 物品性的認證,拿的出某件代表物品就過關,如鑰匙、悠遊卡等票證;3. biometrics: 生物性的認證,你的長相和行為和你以前一樣就過關,如指紋辨識、瞳孔虹膜辨識、人臉辨識、聲音辨識、簽名等等。而要在這麼多選擇當中挑選適合的認證方式,需要考量的關鍵也不少。以便利性來說,biometrics 的方式最方便,什麼都不用帶,你愛認證幾次就認證幾次;反之,passwords 有記一大堆密碼、取太簡單怕被別人猜到、取太難又怕自己記不住的困擾,tokens 則有忘記帶出門或者遺失的風險。以成本來說,passwords 是最便宜的,頂多需要一個簡單的密碼資料庫而已;反之,tokens 有實體物品的成本,biometrics 的認證設備價錢也不便宜。就辨識度而言,比較需要擔心的是 biometrics,畢竟人是活的,手隨時可能被砍斷,臉可能因為表情不同而無法辨識,聲音在感冒的時候總是特別有磁性等等;反之,passwords 和 tokens 就比較一板一眼沒這種變因了。除此之外,不同的認證方式應用在不同地方也會有不同的考量,有需要的話結合多種認證也是一種解決方案。當然,隨著科技的演進,這些考量因素也會有所改變,如果哪天 biometrics 認證發展到又便宜、又普及、可靠度又高到不管你被車撞、整形、還是在模仿藝人都還能認出你來,那麼其他兩種認證方式大概就不再需要了 (這讓人聯想到 DNA 認證,不過到時候應該還有判別複製人兄弟姐妹的困擾吧...)。
回歸正題,目前 passwords 驗證還是最便宜最普及的一種驗證方式,也是這次 project 會採用的方式。而為了提供 project 一個安全的認證系統,了解密碼系統的演進及設計考量 [2] 也勢在必行 (突然發現好像看太多東西了)。像達文西密碼裡密碼盒那種機械式的密碼就不提了,在此討論數位儲存的密碼。最早出現在早期的 UNIX 系統上,由於多工的需求,每個人都必須有自己的帳號和權限,也因此需要密碼作為身分之認證。當時的密碼是以 plaintext 也就是明碼的方式儲存,直到發生因記憶體錯亂導致所有使用者密碼外洩事件之後,plaintext 的儲存方式就馬上被火了,取而代之的是 encryption (e.g. DES) 或 hash (e.g. MD5, SHA-1),透過 decription 或比對 hash 結果來判斷密碼是否吻合。上有政策下有對策,密碼加密過後,壞人們開始想著要怎麼破解。還好上述兩種作法都不太容易,尤其 hash 更是破壞性的加密,用正規數學公式是沒辦法還原的,這時候就只剩「猜」一徒了。可不要小看「猜」這種看似智障的小伎倆,畢竟密碼系統的設計,就是利用字元排列組合有等比級數爆炸成長的特性,造成密碼多到讓你在有生之年都猜不到。以 128 的 ASCII 字元的排列組合來說,8 個字元的密碼就有 128^8 = 7 後面接 16 個零那麼多種組合,假使運算速度快到 1 秒可以做 1000000 次猜測,也需要 2285 年的時間才能猜完全部可能。除非活到猜到為止,同時那個密碼還沒被改,而且那個密碼到時候還有那個價值,否則呆呆的猜是很沒有意義的活動。這時壞人們就開始思考著人性的弱點,密碼最基本的要求是當事者自己要能記住,否則太難的密碼往往記不住而必須貼張便條紙在螢幕上,就像在家門口放把鑰匙是一樣的意思。既然是容易記憶,大概不外乎生日、單字、人名等等,而且為了不讓自己混淆,還一律都用小寫或都用大寫,這大幅縮小了排列組合的可能性,也讓猜密碼的過程減少到幾小時、幾分鐘甚至幾秒的時間。這,就是大名鼎鼎的 Dictionary attack。就目前看到的部分非官方公告或攻擊結果,成功率竟然可以高達 50% 以上,還蠻嚇人的。這也提醒自己在取密碼的時候特別謹慎小心,為了不負密碼設計的本意,最好的狀況就是用到所有可能的 ASCII 字元,同時長度夠長,就能造成排列組合數量多到難以計算而猜不透的效果。同時,為了製造壞人們的困擾,密碼加點 salt 的調味機制,可以讓壞人們無法一次猜多筆密碼,甚至利用運算速度較慢的演算法來拖慢猜密碼的速度,也都是在實作密碼系統可以考量的方向。
是該做點正事了...
[1] L O'Gorman, "Comparing Passwords, Tokens, and Biometrics for User Authentication," Proceedings of the IEEE, 2003
[2] R Morris, K Thompson, "Password Security: A Case History," 1979