iT邦幫忙

2026 iThome 鐵人賽

DAY 21
0
Security

CTF 菜鳥修練日誌系列 第 21 篇

Day 21:【Crypto】雜湊演算法的單向性:MD5/SHA256 碰撞與 Rainbow Table

  • 分享至 

  • xImage
  •  

1. 前言與核心概念

在密碼學中,雜湊函數 (Hash Function) 是確保資料完整性 (Integrity) 與密碼安全儲存的核心基石。

與 RSA 等非對稱加密不同,雜湊演算法屬於單向函數 (One-Way Function):

  • 不可逆性:給定任意長度的輸入 M,可以快速計算出固定長度的雜湊值 H(M);但無法從 H(M) 倒推回原始輸入M。
  • 雪崩效應 (Avalanche Effect):輸入哪怕只改變了一個 bit,產生的雜湊值也會完全不同。

2. 核心漏洞與攻擊手法

1. 碰撞攻擊 (Collision Attack)

理想的雜湊函數應具備抗碰撞性 (Collision Resistance),即找不到兩組不同的輸入 M1 != M2,使得:
Hash(M1) = Hash(M2)

根據鴿籠原理 (Pigeonhole Principle) 與生日悖論 (Birthday Paradox),當輸入空間遠大於輸出空間時,碰撞必然存在。

  • MD5:已被證明在數學結構上極度不安全,可以在數毫秒內透過演算法人為製造出兩份內容不同但 MD5 雜湊值相同的檔案(強碰撞攻擊)。
  • SHA-1:Google 於 2017 年完成 SHAttered 攻擊,成功產出兩份 PDF 檔案擁有相同 SHA-1 值。
  • SHA-256:目前主流且安全的雜湊標準,至今尚未被找到有效的碰撞攻擊手段。

2. 彩虹表與查表攻擊 (Rainbow Table Attack)

由於雜湊演算法無法直接解密,攻擊者若拿到加密資料庫中的密碼雜湊值(例如 5f4dcc3b5aa765d61d8327deb882cf99),通常會採用以下幾種破解策略:

  1. 暴力破解 (Brute-Force):對所有可能的字元組合逐一計算雜湊並比對,極度耗時。
  2. 查表攻擊 (Lookup Table / Dictionary Attack):預先將常見密碼(如 123456, password)算出雜湊值儲存在資料庫中直接查詢。
  3. 彩虹表 (Rainbow Table):為了平衡「儲存空間」與「計算時間」,利用還原函數 (Reduction Function) 將雜湊值交替轉換回字串,形成鏈狀結構(Hash Chain)。彩虹表能以極小的硬盤空間,快速查表還原出未加鹽 (Unsalted) 的密碼。

3. Python 實戰演練

我們利用 Python 來親自驗證 MD5 的單向性破解(彩虹表/字典查表)以及 MD5/SHA256 的雪崩效應。

步驟一:撰寫查表與雜湊驗證腳本

創建 day21_hash_demo.py:

import hashlib

def test_avalanche_effect():
    print("=== 1. 雪崩效應 (Avalanche Effect) 測試 ===")
    text1 = "Hello World"
    text2 = "Hello world"  # 僅 W 改為小寫 w
    
    hash1 = hashlib.sha256(text1.encode()).hexdigest()
    hash2 = hashlib.sha256(text2.encode()).hexdigest()
    
    print(f"輸入 1: '{text1}' -> SHA256: {hash1}")
    print(f"輸入 2: '{text2}' -> SHA256: {hash2}")
    print("-" * 60)

def rainbow_table_crack(target_hash):
    print("=== 2. 彩虹表 / 字典查表攻擊模擬 ===")
    print(f"目標 MD5 Hash: {target_hash}")
    
    # 模擬密碼字典 (Wordlist)
    common_passwords = [
        "admin", "123456", "password", "picoCTF", 
        "iloveyou", "fju_medinfo", "security2026"
    ]
    
    for pwd in common_passwords:
        # 計算字典詞彙的 MD5
        calc_hash = hashlib.md5(pwd.encode()).hexdigest()
        if calc_hash == target_hash:
            print(f"[🎯] 破解成功!對應的原文字串為: '{pwd}'")
            return pwd
            
    print("[-] 字典中未找到匹配的密碼。")
    return None

if __name__ == "__main__":
    test_avalanche_effect()
    
    # 測試破解 'picoCTF' 的 MD5 雜湊值
    target = hashlib.md5("picoCTF".encode()).hexdigest()
    rainbow_table_crack(target)
    ```

### 步驟二:執行結果
在 WSL 終端機執行:

```Bash
python3 day21_hash_demo.py

輸出畫面:

=== 1. 雪崩效應 (Avalanche Effect) 測試 ===
輸入 1: 'Hello World' -> SHA256: a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e
輸入 2: 'Hello world' -> SHA256: 64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c
------------------------------------------------------------
=== 2. 彩虹表 / 字典查表攻擊模擬 ===
目標 MD5 Hash: d5225bf0e85e43c220f1837e28989914
[🎯] 破解成功!對應的原文字串為: 'picoCTF'

https://ithelp.ithome.com.tw/upload/images/20261005/20184211vxRRCetFQ9.png

4. 防禦建議 (Remediation)

面對彩虹表攻擊與雜湊碰撞,現代密碼學儲存密碼時應採用以下防護作為:

1.加入鹽值 (Salting):
在密碼雜湊前加入隨機產生的長字串(Salt),例如 Hash(Password + Salt)。這會使預先計算好的彩虹表無效化,因為攻擊者必須為每個使用者單獨生成彩虹表。

2.使用慢速雜湊演算法 (Key Derivation Functions):
避免直接使用 MD5, SHA256 儲存密碼。應改用加入工作因子 (Work Factor) 的安全演算法,如 Argon2, bcrypt, 或 PBKDF2,故意增加計算延遲,大幅拉高攻擊者的爆破成本。

3.淘汰過時演算法:
禁止將MD5與 SHA-1 用於數位簽章或安全驗證,應統一提升至 SHA-256 或SHA-3系列。


上一篇
Day 20:【Crypto】現代密碼學基石 (二):當 p,q 太近或 e 太小時的 RSA 攻擊
下一篇
Day 22:【Crypto】寫自動化腳本解題:Python pwntools 程式庫基礎
系列文
CTF 菜鳥修練日誌 共 22 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言