Link Search Menu Expand Document

9. 密碼是如何存儲的?

9-1 認識雜湊函數

雜湊函數是一種能將數據變成摘要(digest)的算法,執行 irb,然後輸入以下代碼實驗看看:

require 'digest'
Digest::SHA1.hexdigest '12345678'

得到 "7c222fb2927d828af22f592134e8932480637c0d"

雜湊函數有一些特性:

  1. 相同的數據,每次都會得到一樣的摘要
  2. 是單向的,無法逆推:只知道摘要的話,沒有辦法能夠透過計算知道本來的數據長怎樣。例如給你 7c222fb2927d828af22f592134e8932480637c0d,沒有算法可以逆推回來。除非有一個對照的字典。

9-2 雜湊函數的用途

雜湊函數非常有用,可以拿來快速比較兩個文檔是否相同,而不需要實際比較文檔內容,例如:

  1. Git 每次的 commit,都會有一個摘要。不同的摘要就代表 commit 內容不同。Git 用這個摘要值當作每次 commit 的唯一識別 ID。
  2. 網路傳檔的時候,透過比較這個摘要,就可以知道下載了完整正確的檔案。
  3. 在 Rails 中,Asset pipeline 會將 CSS 和 JavaScript 壓縮,檔名就是透過雜湊函數產生的。這是因為瀏覽器會快取靜態檔案,如果 CSS/Javascript 內容有修改的話,用戶瀏覽器可能不知道有新版而使用到舊的 CSS/JS 檔案。但是因為檔名用了雜湊函數的關系,內容一改檔名就會變得不一樣,那麽瀏覽器就會下載新的檔案了。

image

  1. 存儲用戶密碼。大家已經會用 Devise 在 Rails 中實做 User Model,在 users table 中實際的字段是 encrypted_password

image

image

用戶註冊時輸入的密碼,在實際存儲進資料庫時,會先經過雜湊函數,變成摘要值。資料庫裡面沒有存用戶的明碼,而是存密碼摘要後的值。

而下次用戶要登入的時候,將用戶輸入的密碼摘要一次,與資料庫中存的密碼摘要進行比對,就可以知道密碼對不對了。

這樣的好處是什麽呢?

  1. 資料庫不會存用戶的明碼,所以即使是資料庫管理員,也不會知道用戶真正的密碼是什麽。知道 encrypted_password 並沒有什麽用,因為我們無法逆推。也無法用這個 encrypted_password 做登入。
  2. 萬一資料庫整個外洩了,駭客也無法知道用戶的密碼

不過,目前是市面上仍有很多網站是直接存儲用戶明碼,這會造成用戶隱私很大的危害。因為管理員或駭客(如果資料庫外洩)可以直接看到你密碼,然後很多人在不同網站中,會沿用一樣的密碼。

要怎麽判斷一個網站有沒有存明碼呢?只要試試看忘記密碼程序即可,如果網站直接將你的密碼寄給你,那就代表他的 資料庫存明碼。如果網站要求你重新設定密碼(就像 Devise 一樣),就表示這網站有安全意識。


Copyright © 2010-2021 Wen-Tien Chang All Rights Reserved.