資訊安全:湊雜與加密


在開始之前

最近在複習資訊安全的課程內容,原本以為自己不管在作業及作品實作上,都有考慮到資訊安全的眉角,而進行相關防範,但回頭去檢查時,還是有發現自己疏忽跟大意的地方。

回頭再去看 Huli 的自我檢討文章,發現更新很多我們常犯錯的地方,所以這次的複習,打算先把一些重要的提醒提點出來,然後再來進行後續的觀念整理。

  1. 不要相信任何來自 client 端的資料,保持懷疑精神。
  2. 預設程式碼已經被駭客看光而且被公開,前後台權限管理不能遺漏。
  3. 不要存有僥倖心態, escape、權限管理、prepare statement,做好做滿。
  4. 前端做資料檢查,是為了增進使用者體驗,後端做資料檢查才是真檢查。

明文密碼的風險

透過後端資料庫的設定,儲存會員的密碼資料。若是遇到駭客入侵,盜取資料之後,會員的密碼沒有經過加密處理,將會造成巨大的資安風險:

  1. 如果有駭客駭進了網站資料庫的主機,那所有使用者的帳號、密碼都赤裸裸地攤在駭客的眼前,每個人的帳戶、個人資料都無法倖免。
  2. 如果網站管理者居心不良、或是受到威脅、或是起來上廁所時忘了切換電腦畫面,使用者的帳號、密碼隨時都可能外洩。

為了防止資料庫外洩,不讓密碼輕易被盜取,造成使用者更多的傷害,公司的 IT 團隊會運用一些方式,將原本的密碼加以變化,而最常運用的方式有兩種:「雜湊」和「加密」。

大家是不是有過類似的經驗,我們在登入網站時,如果忘記密碼,按下「忘記密碼」的按鈕,都會請你重設密碼,而不是將原本的密碼透過電子郵件或簡訊回覆提供。真正的原因,就要來了解「雜湊」和「加密」背後的機制。

我們不一樣:雜湊與加密

兩者雖然都有相同的功能:幫使用者的密碼變成亂數排列,但他們根本的差別是:「加密可逆推回到原本的密碼,雜湊不能還原」。

雜湊(Hash):多對一關係,沒辦法從結果回推原本的密碼

  • 如果使用者密碼輸入為「aaa」,透過雜湊的函式,輸出值為「5u8fed7」,我們無從得知雜湊內建函式的演算機制,所以也沒辦法知道「5u8fed7」雜湊之前的原本密碼是「aaa」。
  • 有可能會發生「不同的密碼輸入」卻產生「相同的雜湊值」,若有這樣的狀況,稱為碰撞(collision)。不過,目前現存又知名的雜湊演算法,要發生碰撞的機率非常低。
  • 常見的雜湊演算法:
    • SHA-256
    • MD5(已被證實不安全)
    • SHA-1(已被證實不安全)

加密(Encrypt)

明文密碼經過加密後會產生密文與金鑰(Key),透過金鑰,可以逆推回去原本的明文密碼。

PHP 內建雜湊函式:password_hash

使用之前請注意:支援 PHP v5.5.0 以上版本
使用 PASSWORD_DEFAULT 演算法,注意資料庫預設儲存 255 個字元的空間

@handle_register.php:透過雜湊函式進行密碼加密

<?php 
    $password = password_hash($_POST['password'], PASSWORD_DEFAULT);
 ?>

驗證密碼:password_verify

@handle_login.php:判斷登入時,輸入密碼與雜湊之後的密碼是否相符

<?php 
    $result = $conn->query($sql);
    if (!$result) {
        die($conn->error);
        }

    if ($result->num_rows === 0) {
        header("Location: login.php?errCode=2");
        exit();
    }

    // 有查到使用者
    $row = $result->fetch_assoc();
    if (password_verify($password, $row['password'])) {
        // 登入成功
        $_SESSION['username'] = $username;
        header("Location: index.php");
    } else {
        header("Location: login.php?errCode=2");
    }
?>

雜湊加鹽

為了防堵駭客使用暴力破解法、並建立常用字串對照雜湊值的表單,來突破雜湊密碼防線,我們可以運用「加鹽」(salting)的方式,在密碼進行雜湊之前,先加入一段固定字串(所謂的加鹽),然後與使用者的密碼結合之後,再把加鹽過後的密碼,拿去進行雜湊,產生新的雜湊值之後,存入資料庫,藉以增加駭客破解密碼的難度。

參考資料:
[資訊安全] 密碼存明碼,怎麼不直接去裸奔算了?淺談 Hash , 用雜湊保護密碼
一次搞懂密碼學中的三兄弟 — Encode、Encrypt 跟 Hash
PHP 內建函式表








你可能感興趣的文章

用toObject()取代lean() -TypeError: lean is not a function

用toObject()取代lean() -TypeError: lean is not a function

第二周筆記 (JS) -2

第二周筆記 (JS) -2

C# class, object, method, constructors, getter, setter, static

C# class, object, method, constructors, getter, setter, static






留言討論