[ 筆記 ]資訊安全 - 雜湊密碼:hash


Posted by krebikshaw on 2020-08-13

為什麼密碼要經過雜湊?

一個安全的網頁資料庫應該儲存的是「 經過雜湊的密碼 」而不是使用者輸入時的明碼,這也是為什麼「 按下忘記密碼的按鈕,通常會導到重設密碼、而不是給你原先的密碼,因為資料庫也找不到原碼。」

所以由此推斷出,要是你在某網站按了忘記密碼,系統卻寄了一封「 你原本的密碼 」的 mail,請小心這代表此網站存的是明碼!

存明碼的風險是什麼? 代表此網站的資料庫要是被盜,密碼就被偷走了,所以現代網頁開發應該至少都要做到資料庫被偷,也不至於讓最重要的密碼被拿走或猜出來。

而讓密碼換一層皮的就稱為雜湊。這邊是個大家容易搞混的地方,要注意這步驟、不會稱為加密

雜湊、加密?

雖然目的同樣是讓密碼看起來像亂碼,但兩者最重要的差別就在於:「 加密可逆、雜湊不可密 」

雜湊:單向生成,無法反推出原來的原碼

  • 將不定長度 (無窮可能) 訊息的輸入,演算成 固定長度 雜湊值的輸出,即輸出的長度不受原文長度影響。
  • 同樣的輸入 -> 一定是同樣的輸出
  • 但因為長度是有限的,所以不同輸入也「 可能有同樣的輸出 」,雖然機率非常低,而如有這種情況、又稱為「 碰撞 」Collision。
  • 為了防止被攻擊破解,通常會再加鹽 (salt),指的是再加入一組亂數(有可能是以當下時間為基底的亂數),這樣就算破解了也難以知道原碼,除非連加入亂數的方式也被破解。
  • 常見的雜湊演算法:
    • MD5 ( 已被證實不安全 )
    • SHA-1 ( 已被證實不安全 )
    • SHA-256
      • 比 md5 還強、安全性更高的雜湊函數,但對於伺服器來說,越安全、也代表速度越慢

最常見的攻擊方法:

  • 窮舉法又稱暴力破解 ( brute-force )
    • 就是將所有可能的數列組合都丟進去跑。
    • 長度要是超過一定程度、運算時間會倍增,每增加一字元,密碼組合數量會以數十倍來指數成長。
  • 字典法 ( Dictionary Attacke )
    • 嘗試所有「 常見的密碼 」或使用者的身份資料(親人姓名,電話,出生月日)當作字典資料庫,尤其是出現頻率的密碼組合,例如: password, mypassword, abc123, 1234567… 等等
    • 效率要比窮舉法好得多,特別是資安概念不佳的使用者,但對於密碼無規律者沒效。
  • 彩虹表 ( rainbow table )
    • 指的是把所有可能的輸入都丟進雜湊函數,額外產生一張 hash值 輸出列表,所以本質上也算是一種暴力攻擊法。

加密:拿到密鑰的方式就可以逆推回去

  • 需要密鑰,且可以透過解密得到原文。
  • 分為「 對稱式 」、「 非對稱式 」
  • 對稱式加密:
    • 常見演算法: DES, 3DES, AES
    • 密鑰要是太簡單或長度太短,安全性以及在實際應用上不夠理想,所以出現安全性更高,應用範圍更廣的非對稱式加密(Asymmetric Encryption)。
  • 非對稱式加密:
    • 常見演算法: RSA, DSA, ECC
    • 演算法會有兩把鑰匙,一把稱做公鑰(可以公開),另一把稱做私鑰(自己要藏好)。
    • 可以生成數位簽章,確認密文的傳送方身份真的是本人

PHP 內建雜湊函式 password_hash

(PHP 5 >= 5.5.0, PHP 7)

使用 password hash() 可以直接用最簡單的方式實踐複雜的加密,在使用時,需要搭配第二個參數,推薦直接使用 PASSWORD_DEFAULT

每次處理時,都會在背後產生隨機的 SALT。

當然,也可以手動指定要使用哪一個 SALT,但最好不要,就交給 PASSWORD_DEFAULT 來隨機處理,會更加安全

<?php
$hash = password_hash('your_password', PASSWORD_DEFAULT);
?>

另外也可以搭配第三個 cost 參數 (默認為 10),當值調整越大,所需耗費的計算時間就會越多,可以自行測試。

<?php 
$password = '123456'; // 原始密碼
$hash_password = password_hash($password, PASSWORD_DEFAULT);
if (password_verify($password , $hash_password)){
   echo "密碼正確";
}else{  
   echo "密碼錯誤";
}
?>









Related Posts

Web開發學習筆記10 — 預設參數、Spread Operator、Rest Operator、解構賦值、陣列方法的練習筆記

Web開發學習筆記10 — 預設參數、Spread Operator、Rest Operator、解構賦值、陣列方法的練習筆記

簡明程式解題入門 - 陣列篇 IV

簡明程式解題入門 - 陣列篇 IV

There's no hierarchy of pain

There's no hierarchy of pain


Comments