2012年1月9日

密碼應該怎麼存?

最近明文密碼的話題很紅,
決定來重貼以前關於密碼編碼(password hashing)的筆記:

  • 編碼(hash)時請記得加鹽(salt)
  • 不要整個系統都用一樣的 salt,請每次都以亂數方式產生。
  • 把 salt 跟 hash 放一起,不要分開存。
  • 結合方式最好可以有變化,
    例如:由明碼長度決定 salt 的插入位置。

用 PHP 寫起來大概像這樣:

$salt = substr(hash_func(uniqid(rand(), true)), 0, $saltLen);

$hash = hash_func($salt . $plain);

$saltStart = strlen($plain);
return substr($hash,0,$saltStart) . $salt . substr($hash,$saltStart+1);

另外,理想狀況是客戶端跟伺服器端間以加密方式(如,SSL)傳遞密碼。但是事情往往沒有這麼美好,沒辦法用 SSL 的話,可以參考〔延伸閱讀〕第 3 篇提到的「瀏覽器端 hash」。

@yllan 補充

密碼不要用 md5 比較好,要找比較難算的 hash function 例如 bcrypt 可以參數調整難易度。否則就算加了鹽,md5 還是很容易 crack

@yunglinho 補充: 《How To Safely Store A Password

  • Salts Will Not Help You
  • Use bcrypt

延伸閱讀:

  1. 密碼為什麼不能存「明文」? | 我的密碼沒加密
  2. A Basic Lesson in Password Hashing - seanmonstar
  3. hoamon's sandbox: 不應該在資料庫中紀錄使用者的明碼密碼