在現今的網路環境中,資料安全至關重要。雜湊函式是確保資料完整性的核心技術,本文將深入探討 Python 內建的 hashlib 模組,以及如何使用 SHA-256、HMAC 等技術保護資料安全。我們將比較不同雜湊函式的特性,包括 SHA-2、SHA-3 和 BLAKE2 家族,並指出 MD5 的安全性問題。同時,文章也將示範如何使用 Python 程式碼計算雜湊值,並使用 HMAC 進行訊息驗證,確保資料的真實性與完整性,最後將探討如何避免時間攻擊等安全風險。

第2章:雜湊函式

在前一章中,我們討論了資料完整性的重要性。現在,我們將深入探討如何使用雜湊函式來確保資料的完整性。

2.4 選擇加密雜湊函式

Python 已經內建了對加密雜湊的支援,因此我們不需要額外的函式庫或框架。內建的 hashlib 模組提供了所有我們需要的加密雜湊函式。algorithms_guaranteed 列表包含了所有保證在所有平臺上可用的雜湊函式。

import hashlib
print(sorted(hashlib.algorithms_guaranteed))

這將列出所有保證可用的雜湊函式,包括 blake2bblake2smd5sha1sha224sha256sha384sha3_224sha3_256sha3_384sha3_512sha512shake_128shake_256

2.4.1 安全的雜湊函式

安全的雜湊函式分為三個家族:SHA-2、SHA-3 和 BLAKE2。

SHA-2

SHA-2 雜湊函式家族由 NSA 於 2001 年提出,包括 SHA-224、SHA-256、SHA-384 和 SHA-512。其中,SHA-256 是最常用的,並且是本章後續章節中將要反覆提到的。

SHA-3

SHA-3 雜湊函式家族包括 SHA3-224、SHA3-256、SHA3-384、SHA3-512、SHAKE128 和 SHAKE256。SHA-3 被認為是 SHA-2 的繼任者,但在本章寫作時尚未得到廣泛應用。

BLAKE2

BLAKE2 雜湊函式家族包括 BLAKE2b 和 BLAKE2s。BLAKE2b 設計為 64 位平臺,而 BLAKE2s 則適用於 8 位至 32 位平臺。BLAKE2 的優點在於其能夠充分利用現代 CPU 的能力,以超高速度計算雜湊值。

2.4.2 不安全的雜湊函式

雖然 algorithms_guaranteed 列表中的所有雜湊函式都具有良好的跨平臺相容性,但並非所有函式都適合用於加密目的。其中,MD5 就是一個不安全的雜湊函式,已經不再被視為安全的選擇。

內容解密:

上述程式碼片段使用 Python 的 hashlib 模組列出所有保證可用的雜湊函式。這些函式包括了安全和不安全的選擇,因此在選擇時需要謹慎考慮。

圖表翻譯:

下圖示意了不同雜湊函式之間的關係和特點。

  graph TD
    A[SHA-2] -->|包含|> B[SHA-224]
    A -->|包含|> C[SHA-256]
    A -->|包含|> D[SHA-384]
    A -->|包含|> E[SHA-512]
    F[SHA-3] -->|包含|> G[SHA3-224]
    F -->|包含|> H[SHA3-256]
    F -->|包含|> I[SHA3-384]
    F -->|包含|> J[SHA3-512]
    K[BLAKE2] -->|包含|> L[BLAKE2b]
    K -->|包含|> M[BLAKE2s]
    N[MD5] -->|不安全|> O[加密目的]

這個圖表展示了 SHA-2、SHA-3 和 BLAKE2 等安全雜湊函式家族,以及 MD5 等不安全的選擇。

加密雜湊函式的選擇

在進行資料加密和驗證時,選擇合適的加密雜湊函式(hash function)至關重要。雜湊函式是一種將輸入資料轉換為固定長度的字串,稱為雜湊值(hash value)的演算法。不同的雜湊函式有不同的特性和安全性,因此選擇合適的雜湊函式是非常重要的。

不安全的雜湊函式

有一些雜湊函式已經被證明是不安全的,例如MD5和SHA-1。MD5是一種128位元的雜湊函式,曾經被廣泛使用,但是在2004年被發現有碰撞(collision)的問題,即兩個不同的輸入資料可以產生相同的雜湊值。SHA-1是一種160位元的雜湊函式,也曾經被廣泛使用,但是在2017年被發現有碰撞的問題。

安全的雜湊函式

目前,SHA-256是一種被廣泛接受的安全雜湊函式。它是一種256位元的雜湊函式,被設計為具有高安全性和低碰撞率。SHA3-256是一種新的雜湊函式,具有更高的安全性,但其支援度不如SHA-256。BLAKE2是一種快速且安全的雜湊函式,適合於處理大型資料。

選擇雜湊函式的原則

選擇雜湊函式時,應該考慮以下幾個原則:

  • 安全性:選擇具有高安全性的雜湊函式,例如SHA-256或SHA3-256。
  • 速度:選擇快速的雜湊函式,例如BLAKE2。
  • 支援度:選擇具有廣泛支援度的雜湊函式,例如SHA-256。

Python中的加密雜湊函式

在Python中,可以使用hashlib模組來實作加密雜湊函式。hashlib模組提供了多種加密雜湊函式,包括SHA-256、SHA3-256和BLAKE2。以下是使用hashlib模組來實作SHA-256加密雜湊函式的範例:

import hashlib

# 建立SHA-256加密雜湊函式
hash_function = hashlib.sha256()

# 設定輸入資料
input_data = b"Hello, World!"

# 更新加密雜湊函式
hash_function.update(input_data)

# 取得加密雜湊值
hash_value = hash_function.digest()

# 輸出加密雜湊值
print(hash_value.hex())

MD5 雜湊碰撞示例

MD5(資訊摘要演算法 5)是一種常用的加密雜湊函式,但它已經被發現存在碰撞漏洞,即不同的輸入可以產生相同的雜湊值。下面是展示 MD5 雜湊碰撞的示例。

示例程式碼

from hashlib import md5

# 定義兩個不同的輸入
x = bytearray.fromhex('d131dd02c5e6eec4693d9a0698aff95c2fcab58712467eab4004583eb8fb7f8955ad340609f4b30283e488832571415a085125e8f7cdc99fd91dbdf280373c5bd8823e3156348f5bae6dacd436c919c6dd53e2b487da03fd02396306d248cda0e99f33420f577ee8ce54b67080a80d1ec69821bcb6a8839396f9652b6ff72a70')
y = bytearray.fromhex('d131dd02c5e6eec4693d9a0698aff95c2fcab50712467eab4004583eb8fb7f8955ad340609f4b30283e4888325f1415a085125e8f7cdc99fd91dbd7280373c5bd8823e3156348f5bae6dacd436c919c6dd53e23487da03fd02396306d248cda0e99f33420f577ee8ce54b67080280d1ec69821bcb6a8839396f965ab6ff72a70')

# 建立 MD5 雜湊物件
hash_function_x = md5(x)
hash_function_y = md5(y)

# 輸出雜湊值
print("x 的雜湊值(十六進位制):", hash_function_x.hexdigest())
print("y 的雜湊值(十六進位制):", hash_function_y.hexdigest())

執行結果

x 的雜湊值(十六進位制): 79054025255a061a4d79c4aa47bb052a
y 的雜湊值(十六進位制): 79054025255a061a4d79c4aa47bb052a

分析

從執行結果可以看到,儘管 xy 兩個輸入不同,但它們的 MD5 雜湊值卻相同,這就是所謂的雜湊碰撞。這個示例展示了 MD5 演算法存在的安全漏洞,表明它不適合用於安全性要求高的應用中。

圖表翻譯:

  graph LR
    A[輸入 x] -->|MD5 雜湊|> B[雜湊值]
    C[輸入 y] -->|MD5 雜湊|> D[雜湊值]
    B --> E[比較]
    D --> E
    E -->|結果|> F[碰撞]

內容解密:

  1. 輸入: xy 是兩個不同的輸入,它們被轉換為 bytearray 型別以便進行雜湊計算。
  2. MD5 雜湊: 對 xy 進行 MD5 雜湊計算,得到兩個雜湊物件 hash_function_xhash_function_y
  3. 雜湊值: 使用 hexdigest() 方法得到雜湊值的十六進製表示。
  4. 比較: 對兩個雜湊值進行比較,以檢查是否發生碰撞。
  5. 結果: 如果兩個雜湊值相同,則表示發生了碰撞,否則表示沒有碰撞。

這個示例強調了在安全性要求高的應用中,應該選擇更安全的雜湊演算法,如 SHA-256 或 SHA-3。

數學公式與雜湊函式

在電腦科學中,雜湊函式是一種將輸入資料(如字串或資料)對映到固定大小的字串(即雜湊值)的函式。這個過程稱為雜湊化。雜湊函式常用於資料儲存和檢索、密碼學和資料完整性等領域。

雜湊函式的性質

  1. 決定性:給定輸入,雜湊函式總是會產生相同的輸出。
  2. 不可逆:無法從雜湊值反推輸入資料。
  3. 固定輸出大小:無論輸入資料大小如何,雜湊值的大小始終相同。

Python 中的雜湊函式

Python 的 hashlib 模組提供了多種雜湊函式的實作,包括 SHA-256、MD5 等。

import hashlib

# 建立一個 SHA-256 雜湊物件
hash_function = hashlib.sha256()

# 更新雜湊物件的內容
hash_function.update(b'message')

# 取得雜湊值
hash_value = hash_function.digest()

print(hash_value)

雜湊碰撞

當兩個不同的輸入資料產生相同的雜湊值時,稱為雜湊碰撞。雖然雜湊碰撞在理論上是可能的,但是在實踐中極為罕見。

雜湊函式的應用

  1. 資料完整性:透過計算資料的雜湊值,可以檢查資料是否被篡改。
  2. 密碼學:雜湊函式常用於密碼學演算法中,以保護資料的安全。
  3. 資料儲存和檢索:雜湊函式可以用於快速定位和檢索資料。

Latex 數學公式

在 Markdown 中,可以使用 Latex 語法插入數學公式。例如:

$$x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}$$

這個公式是二次方程的解法。

2.5 加密雜湊函式

加密雜湊函式(Cryptographic Hash Functions)是一種特殊的演算法,能夠將任意長度的輸入資料轉換成固定長度的雜湊值。這些函式具有以下特性:

  • 決定性:給定相同的輸入,總是會產生相同的輸出。
  • 不可逆:無法從雜湊值逆向推匯出原始輸入資料。
  • 固定輸出大小:無論輸入資料的大小如何,輸出的雜湊值始終是相同的大小。

2.5.1 SHA-256 雜湊函式

SHA-256 是一種廣泛使用的加密雜湊函式,能夠產生 256 位元的雜湊值。它被設計用於資料完整性和真實性驗證。

以下是使用 Python 和 Ruby 進行 SHA-256 雜湊計算的範例:

import hashlib

# 輸入資料
data = b"m"

# 進行 SHA-256 雜湊計算
hash_value = hashlib.sha256(data).hexdigest()

print(hash_value)
require "digest"

# 輸入資料
data = "m"

# 進行 SHA-256 雜湊計算
hash_value = Digest::SHA256.hexdigest(data)

puts hash_value

這兩個範例都會輸出相同的雜湊值:62c66a7a5dd70c3146618063c344e531e6d4b59e379808443ce962b3abd63c5a

2.5.2 內建雜湊函式

Python 的內建 hash() 函式可以用於計算雜湊值,但是它不適合用於加密目的。這是因為 hash() 函式的設計目的是為了快速計算雜湊值,而不是為了提供加密安全性。

以下是使用 hash() 函式進行雜湊計算的範例:

# 輸入資料
data = "message"

# 進行雜湊計算
hash_value = hash(data)

print(hash_value)

請注意,hash() 函式的輸出可能會因為 Python 的版本和平臺而異。

2.5.3 檢查碼函式

檢查碼函式(Checksum Functions)是一種用於檢查資料完整性的技術。它們能夠計算出資料的檢查碼,並用於檢查資料是否被修改過。

Python 的 zlib 模組提供了 CRC-32 和 Adler-32 等檢查碼函式。以下是使用 CRC-32 進行檢查碼計算的範例:

import zlib

# 輸入資料
data = b"this is repetitious" * 42

# 進行 CRC-32 檢查碼計算
checksum = zlib.crc32(data)

print(checksum)

檢查碼函式和加密雜湊函式都能夠用於檢查資料完整性,但是它們之間存在著一些差異。檢查碼函式計算得更快,但是它們不如加密雜湊函式那樣安全。

圖表翻譯:

  graph LR
    A[輸入資料] --> B[加密雜湊函式]
    B --> C[固定長度的雜湊值]
    C --> D[檢查資料完整性]
    D --> E[確認資料是否被修改過]

此圖表展示了加密雜湊函式的工作流程,從輸入資料到產生固定長度的雜湊值,再到檢查資料完整性和確認資料是否被修改過。

2.6 檢查碼函式

檢查碼函式是一種用於檢查資料完整性的技術。它們能夠計算出資料的檢查碼,並用於檢查資料是否被修改過。

Python 的 zlib 模組提供了 CRC-32 和 Adler-32 等檢查碼函式。以下是使用 CRC-32 進行檢查碼計算的範例:

import zlib

# 輸入資料
data = b"this is repetitious" * 42

# 進行 CRC-32 檢查碼計算
checksum = zlib.crc32(data)

print(checksum)

檢查碼函式和加密雜湊函式都能夠用於檢查資料完整性,但是它們之間存在著一些差異。檢查碼函式計算得更快,但是它們不如加密雜湊函式那樣安全。

內容解密:

上述程式碼展示瞭如何使用 Python 的 zlib 模組進行 CRC-32 檢查碼計算。首先,輸入資料被定義為 data 變數。然後,使用 zlib.crc32() 函式進行 CRC-32 檢查碼計算,並將結果儲存到 checksum 變數中。最後,印出 checksum 變數的值。

圖表翻譯:

  graph LR
    A[輸入資料] --> B[檢查碼函式]
    B --> C[檢查碼]
    C --> D[檢查資料完整性]
    D --> E[確認資料是否被修改過]

此圖表展示了檢查碼函式的工作流程,從輸入資料到產生檢查碼,再到檢查資料完整性和確認資料是否被修改過。

資料完整性與真實性驗證

在前一章中,我們學習瞭如何使用雜湊函式來驗證資料的完整性。但是,僅僅驗證資料的完整性是不夠的,因為攻擊者可能會同時修改資料和雜湊值。因此,我們需要有一種方法來驗證資料的真實性,即驗證資料是由誰建立的。

生成安全的隨機數字和密碼

要驗證資料的真實性,我們需要生成一個安全的隨機數字或密碼作為金鑰。Python 的 secrets 模組提供了一種安全的方式來生成隨機數字和密碼。

import secrets

# 生成一個安全的隨機數字
random_number = secrets.randbelow(100)
print(random_number)

# 生成一個安全的密碼
password = secrets.token_urlsafe(16)
print(password)

使用 HMAC 來驗證資料真實性

HMAC(Keyed-Hashing for Message Authentication)是一種使用雜湊函式和金鑰來驗證資料真實性的方法。Python 的 hmac 模組提供了一種實作 HMAC 的方式。

import hmac
import hashlib

# 生成一個安全的隨機數字作為金鑰
key = secrets.token_bytes(16)

# 要驗證的資料
data = b"Hello, World!"

# 使用 HMAC 來驗證資料真實性
hmac_value = hmac.new(key, data, hashlib.sha256).digest()
print(hmac_value)

預防時間攻擊

時間攻擊是一種攻擊者嘗試透過分析系統的反應時間來取得敏感資訊的方法。要預防時間攻擊,我們可以使用一個固定時間來比較雜湊值。

import time

# 要比較的兩個雜湊值
hmac_value1 = b"..."
hmac_value2 = b"..."

# 固定時間比較雜湊值
start_time = time.time()
if hmac_value1 == hmac_value2:
    print("雜湊值相同")
else:
    print("雜湊值不同")
end_time = time.time()
print("比較時間:", end_time - start_time)

3.1.1 金鑰生成

任何秘密金鑰都應該是難以猜測的。在本文中,我們將比較兩種金鑰型別:隨機數字和密碼短語。特別是,描述瞭如何生成它們以及何時使用哪種型別的金鑰。

隨機數字

為了生成隨機數字,不需要第三方函式庫,Python 本身就有足夠的方法來建立它們。但是,並非所有方法都適合於安全目的。開發人員通常使用 os.urandom 函式作為密碼安全的隨機數字源。作為引數,它接受一個整數 size 並傳回相應數量的隨機位元組。這些位元組的源頭是作業系統本身。在 UNIX-like 系統中,這是 /dev/urandom,在 Windows 中,這是 CryptGenRandom

import os

print(os.urandom(16))

Python 3.6 中的 secrets 模組

在 Python 3.6 中,特別為了生成密碼安全的隨機數字而增加了 secrets 模組。雖然 os.urandom 做得很好,但是在本章中,我們使用 secrets 來生成隨機數字。它包含三個方便的函式來生成隨機數字。所有這些函式都接受一個整數作為引數並傳回隨機數字。這些數字可以是位元組陣列、十六進位制文字或用於插入 URL 的文字。所有這些函式都有 token_ 字首:

from secrets import token_bytes, token_hex, token_urlsafe

print(token_bytes(16))
print(token_hex(16))
print(token_urlsafe(16))

random 模組

random 模組是第三種方法來獲得隨機數字。大多數來自此模組的函式傳回不安全的值。在其檔案中明確指出:「不應該用於安全目的」。與此同時,secrets 模組被宣佈為首選模組。

警告! 絕不能在防禦和密碼學任務中使用 random 模組。它非常適合於一般應用,但不適合於構建安全機制。

密碼短語

密碼短語是一組隨機單詞,而不是數字。在以下列表中,我們展示瞭如何使用 secrets 模組從四個單詞中建立一個密碼短語。單詞來自一個檔案,作為詞典。

首先,詞典被載入到記憶體中。它通常隨 UNIX-like 系統一起提供。如果您使用的是不同的系統,您可能需要下載或安裝詞典。

然後,使用 secrets.choice 函式從單詞列表中選擇一個隨機單詞。這個函式通常用於傳回一個序列中的隨機元素。

from pathlib import Path
import secrets

words = Path('/usr/share/dict/words').read_text().splitlines()
passphrase = ' '.join(secrets.choice(words) for _ in range(4))

print(passphrase)

請注意,類別似的詞典也被攻擊者用於暴力攻擊。因此,從詞典中選擇單詞來建立密碼並不是一個明智的想法。然而,密碼短語的長度可以提供額外的安全性。例如,“whereat isostatic custom insupportableness” 這個短語長度為 42 個位元組。

什麼是加密技術?

加密技術是一種用於保護資料安全的方法,透過將明文轉換為密鑰,使得未經授權的人無法閱讀或竊取資料。

加密技術的型別

加密技術可以分為對稱加密和非對稱加密兩種。對稱加密使用相同的金鑰進行加密和解密,而非對稱加密使用一對金鑰:公鑰和私鑰。

數字簽名的重要性

數字簽名是用於驗證資料真實性和完整性的技術,透過使用加密技術和雜湊函式生成的數字指紋,可以確保資料在傳輸過程中未被竄改或偽造。

雜湊函式的作用

雜湊函式是一種將輸入資料對映為固定長度的字串的演算法,常用於生成數字指紋和驗證資料完整性。

密碼學中的安全性

密碼學中的安全性是指保護資料免受未經授權的存取、竊聽、竄改和偽造的能力,透過使用加密技術、數字簽名和雜湊函式等方法,可以確保資料的安全性和完整性。

實際應用案例

在實際應用中,加密技術和數字簽名被廣泛用於各個領域,例如網路安全、電子商務、金融交易等,以保護敏感資料和確保交易的安全性。

程式碼實作示例

import hashlib

def generate_hash(data):
    # 使用 SHA-256 雜湊函式生成數字指紋
    hash_value = hashlib.sha256(data.encode()).hexdigest()
    return hash_value

def verify_hash(data, hash_value):
    # 驗證資料完整性
    generated_hash = generate_hash(data)
    return generated_hash == hash_value

# 測試
data = "Hello, World!"
hash_value = generate_hash(data)
print(f"Hash Value: {hash_value}")

is_valid = verify_hash(data, hash_value)
print(f"Is Valid: {is_valid}")

內容解密:

上述程式碼示例使用 SHA-256 雜湊函式生成數字指紋,並驗證資料完整性。這是一個基本的例子,展示瞭如何使用加密技術和雜湊函式保護資料安全。

圖表翻譯:

  flowchart TD
    A[資料] --> B[雜湊函式]
    B --> C[數字指紋]
    C --> D[驗證]
    D --> E[結果]

圖表翻譯:

上述圖表展示了加密技術和數字簽名的流程,從輸入資料到生成數字指紋,然後驗證資料完整性,最終得到結果。這個流程是保護資料安全的基本步驟。

HMAC函式:根據雜湊的訊息驗證碼

HMAC(Hash-based Message Authentication Code)是一種廣泛使用的技術,用於驗證資料的完整性和真實性。它根據雜湊函式,允許使用者將任意雜湊函式應用於訊息驗證。

HMAC函式的工作原理

HMAC函式需要三個引數:訊息、金鑰和雜湊函式。它傳回一個驗證碼(MAC),該驗證碼是訊息和金鑰的雜湊值。HMAC函式可以使用任何雜湊函式,例如SHA-256。

Python中的HMAC實作

Python的hmac模組提供了HMAC函式的實作。以下是使用hmac模組計算HMAC-SHA256的例子:

import hashlib
import hmac

# 設定金鑰和訊息
key = b'key'
msg = b'message'

# 建立HMAC-SHA256物件
hmac_sha256 = hmac.new(key, msg, hashlib.sha256)

# 計算HMAC值
hmac_value = hmac_sha256.digest()

# 輸出HMAC值
print(hmac_value.hex())

HMAC函式的應用

HMAC函式廣泛應用於各種領域,包括:

  • 資料完整性驗證:確保資料在傳輸或儲存過程中沒有被篡改。
  • 身份驗證:確保使用者的身份和許可權。
  • 會話管理:確保會話的完整性和安全性。

HMAC函式的優點

HMAC函式具有以下優點:

  • 高效:HMAC函式計算速度快,適合於大規模資料處理。
  • 安全:HMAC函式根據雜湊函式,具有良好的安全性和抗碰撞性。
  • 靈活:HMAC函式可以使用任何雜湊函式,適合於不同的應用場景。

雜湊函式在保障資料安全方面扮演著至關重要的角色。深入剖析雜湊函式的特性,可以發現其單向性、抗碰撞性和固定輸出長度等特性,是確保資料完整性、驗證資料真實性和保護敏感資訊的基本。SHA-256 和 BLAKE2 等演算法已成為業界標準,展現出高度的安全性與效能。然而,技術限制依然存在,例如雜湊碰撞的可能性,雖然機率極低,但仍需考量。此外,量子計算的發展也可能對現有雜湊演算法的安全性構成挑戰。

對於實務應用,選擇合適的雜湊函式至關重要。考量安全性、效能和支援度等因素,SHA-256 通常是較佳的選擇。同時,應避免使用已知不安全的雜湊函式,例如 MD5 和 SHA-1。此外,HMAC 的應用能進一步提升資料驗證的安全性,有效防止資料篡改和偽造。技術團隊應關注金鑰管理的安全性,並持續更新雜湊演算法以應對新的安全威脅。

展望未來,隨著量子計算的發展,抗量子雜湊演算法的研究將成為新的技術熱點。同時,結合其他加密技術,例如非對稱加密和數位簽章,將進一步提升資料安全的保障等級。玄貓認為,持續關注雜湊函式的技術演進,並將其與其他安全機制整合,是構建穩固安全體系的關鍵策略。