關於Python雜湊演算法的必要知識

關於Python雜湊演算法的必要知識

Python 程式使用雜湊(又稱雜湊)將輸入資料轉換成一個固定大小的值。該值唯一地表示資料,雜湊技術使各種形式的資料的安全傳輸和儲存變得容易。

雜湊可以保護資料免受未經授權的訪問和篡改。它是資料完整性和安全用例中的重要組成部分。

本文探討了關於 Python 雜湊所需瞭解的一切。它深入探討了雜湊的用途,並重點介紹了各種雜湊演算法,這些演算法可使您的程式碼更加高效、安全和可靠。

什麼是 Python 中的雜湊?

雜湊將輸入資料(如字串、檔案或物件)轉換為固定大小的位元組串。雜湊值或摘要以唯一且可重現的方式表示輸入。

雜湊在檢測資料操作和增強安全性方面發揮著重要作用。它可以為檔案、資訊或其他資料計算雜湊值。應用程式可以安全地儲存雜湊值,以便日後驗證資料是否被篡改。

雜湊值在安全方面最常見的用途之一就是密碼儲存。雜湊是在資料庫中儲存純文字密碼的一種可行替代方法。當使用者輸入密碼時,系統會先對密碼進行雜湊處理,然後再將其儲存到資料庫中。如果黑客訪問資料庫,他們會發現密碼很難被竊取。

Python 雜湊函式使這一切成為可能。這些數學函式可以讓應用程式將資料處理成雜湊值。

如何製作有效的雜湊函式

雜湊函式應符合以下標準,才能有效且安全:

  • 確定性 – 給定相同的輸入,函式應始終返回相同的輸出。
  • 高效 – 在計算任何給定輸入的雜湊值時,它應具有較高的計算效率。
  • 抗碰撞 – 函式應儘量減少兩個輸入產生相同雜湊值的機率。
  • 均勻性 – 函式的輸出應均勻分佈在可能的雜湊值範圍內。
  • 不可逆轉 – 計算機不可能根據雜湊值計算出函式的輸入值。
  • 不可預測 – 在給定一組輸入的情況下,預測函式的輸出應具有挑戰性。
  • 對輸入變化敏感 – 函式應對輸入中的微小差異非常敏感。微小的變化應導致結果雜湊值的巨大差異。

雜湊使用案例

一旦掌握了具備所有這些特性的雜湊函式,就可以將其應用於各種用例。雜湊函式可以很好地用於:

  • 密碼儲存 – 雜湊是現代系統中儲存使用者密碼的最佳方法之一。Python 結合各種模組對密碼進行雜湊並確保其安全,然後再將其儲存到資料庫中。
  • 快取 – 雜湊可以儲存函式的輸出,以便在以後呼叫時節省時間。
  • 資料檢索 – Python 使用帶有內建字典資料結構的雜湊表,可按鍵快速檢索值。
  • 數字簽名 – 雜湊可以驗證具有數字簽名的資訊的真實性。
  • 檔案完整性檢查 – 雜湊可以檢查檔案在傳輸和下載過程中的完整性。

Python 內建雜湊函式

Python 內建的雜湊函式 hash() 返回一個代表輸入物件的整數值。然後,程式碼使用得到的雜湊值來確定物件在雜湊表中的位置。雜湊表是一種實現了字典和集合的資料結構。

下面的程式碼演示了 hash() 函式如何工作:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
my_string = "hello world"
# Calculate the hash value of the string
hash_value = hash(my_string)
# Print the string and its hash value
print("String: ", my_string)
print("Hash value: ", hash_value)
my_string = "hello world" # Calculate the hash value of the string hash_value = hash(my_string) # Print the string and its hash value print("String: ", my_string) print("Hash value: ", hash_value)
my_string = "hello world"
# Calculate the hash value of the string
hash_value = hash(my_string)
# Print the string and its hash value
print("String: ", my_string)
print("Hash value: ", hash_value)

如果我們將程式碼儲存在名為 hash.py 的檔案中,就可以像這樣執行它(並檢視輸出):

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
% python3 hash.py
String: hello world
Hash value: 2213812294562653681
% python3 hash.py String: hello world Hash value: 2213812294562653681
% python3 hash.py
String:  hello world
Hash value:  2213812294562653681

讓我們再執行一次:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
% python3 hash.py
String: hello world
Hash value: -631897764808734609
% python3 hash.py String: hello world Hash value: -631897764808734609
% python3 hash.py
String:  hello world
Hash value:  -631897764808734609

由於最近釋出的 Python(3.3 及更高版本)預設為該函式應用隨機雜湊種子,因此第二次呼叫時的雜湊值是不同的。每次呼叫 Python 時,種子都會改變。在單個例項中,結果將是相同的。

例如,讓我們把這段程式碼放到 hash.py 檔案中:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
my_string = "hello world"
# Calculate 2 hash values of the string
hash_value1 = hash(my_string)
hash_value2 = hash(my_string)
# Print the string and its hash values
print("String: ", my_string)
print("Hash value 1: ", hash_value1)
print("Hash value 2: ", hash_value2)
my_string = "hello world" # Calculate 2 hash values of the string hash_value1 = hash(my_string) hash_value2 = hash(my_string) # Print the string and its hash values print("String: ", my_string) print("Hash value 1: ", hash_value1) print("Hash value 2: ", hash_value2)
my_string = "hello world"
# Calculate 2 hash values of the string
hash_value1 = hash(my_string)
hash_value2 = hash(my_string)
# Print the string and its hash values
print("String: ", my_string)
print("Hash value 1: ", hash_value1)
print("Hash value 2: ", hash_value2)

執行時,我們會看到這樣的畫面:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
String: hello world
Hash value 1: -7779434013116951864
Hash value 2: -7779434013116951864
String: hello world Hash value 1: -7779434013116951864 Hash value 2: -7779434013116951864
String: hello world
Hash value 1:  -7779434013116951864
Hash value 2:  -7779434013116951864

雜湊的侷限性

儘管 Python 的雜湊函式在各種用例中都很有前途,但它的侷限性使其不適合用於安全目的。下面就來看看它的侷限性:

  • 碰撞攻擊 – 當兩個不同的輸入產生相同的雜湊值時,就會發生碰撞。攻擊者可以使用相同的輸入方法繞過依賴雜湊值進行身份驗證或資料完整性檢查的安全措施。
  • 有限的輸入大小 – 由於雜湊函式會產生固定大小的輸出,而與輸入的大小無關,因此大於雜湊函式輸出的輸入會導致碰撞。
  • 可預測性 – 雜湊函式應具有確定性,每次提供相同的輸入都會產生相同的輸出。攻擊者可能會利用這一弱點,預先編譯許多輸入的雜湊值,然後將它們與目標值雜湊值進行比較,找出匹配的結果。這個過程被稱為彩虹表攻擊。

為防止攻擊並確保資料安全,請使用專為抵禦此類漏洞而設計的安全雜湊演算法。

在 Python 中使用 hashlib 實現安全雜湊

與其使用內建的 Python hash() ,不如使用 hashlib 來獲得更安全的雜湊。該 Python 模組提供了多種安全雜湊資料的雜湊演算法。這些演算法包括 MD5、SHA-1 和更安全的 SHA-2 系列,包括 SHA-256、SHA-384、SHA-512 等。

MD5

廣泛使用的加密演算法 MD5 能生成 128 位的雜湊值。使用下面的程式碼,使用 hashlibmd5 建構函式生成 MD5 雜湊值:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import hashlib
text = "Hello World"
hash_object = hashlib.md5(text.encode())
print(hash_object.hexdigest())
import hashlib text = "Hello World" hash_object = hashlib.md5(text.encode()) print(hash_object.hexdigest())
import hashlib
text = "Hello World"
hash_object = hashlib.md5(text.encode())
print(hash_object.hexdigest())

上述結果(在我們的 hash.py 檔案中)在不同的呼叫中將保持一致:

b10a8db164e0754105b7a99be72e3fe5

注:上述程式碼中的 hexdigest() 方法以十六進位制格式返回雜湊值,可用於任何非二進位制表達(如電子郵件)。

SHA-1

SHA-1 雜湊函式通過生成一個 160 位的雜湊值來確保資料安全。使用下面的程式碼和 sha1 建構函式來獲取 hashlib 模組的 SHA-1 雜湊值:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import hashlib
text = "Hello World"
hash_object = hashlib.sha1(text.encode())
print(hash_object.hexdigest())
import hashlib text = "Hello World" hash_object = hashlib.sha1(text.encode()) print(hash_object.hexdigest())
import hashlib
text = "Hello World"
hash_object = hashlib.sha1(text.encode())
print(hash_object.hexdigest())

上述結果的輸出:

0a4d55a8d778e5022fab701977c5d840bbc486d0

SHA-256

SHA-2 系列有多種雜湊選項。hashlib SHA-256 建構函式可生成該系列中更安全的 256 位雜湊值。

程式設計師經常將 SHA-256 用於加密,如數字簽名或訊息驗證碼。下面的程式碼演示瞭如何生成 SHA-256 雜湊值:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import hashlib
text = "Hello World"
hash_object = hashlib.sha256(text.encode())
print(hash_object.hexdigest())
import hashlib text = "Hello World" hash_object = hashlib.sha256(text.encode()) print(hash_object.hexdigest())
import hashlib
text = "Hello World"
hash_object = hashlib.sha256(text.encode())
print(hash_object.hexdigest())

上述結果的輸出:

a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e

SHA-384

SHA-384 是一個 384 位的雜湊值。程式設計師經常在需要提高資料安全性的應用程式中使用 SHA-384 函式。

根據前面的示例,你大概可以猜到這是一條生成 SHA-384 雜湊值的語句:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
hash_object = hashlib.sha384(text.encode())
hash_object = hashlib.sha384(text.encode())
hash_object = hashlib.sha384(text.encode())

SHA-512

SHA-512 是 SHA-2 家族中最安全的成員。它能生成 512 位的雜湊值。程式設計師將其用於高吞吐量應用,如檢查資料完整性。下面的程式碼展示瞭如何使用 Python 中的 hashlib 模組生成 SHA-512 雜湊值:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
hash_object = hashlib.sha512(text.encode())
hash_object = hashlib.sha512(text.encode())
hash_object = hashlib.sha512(text.encode())

如何選擇雜湊演算法

由於這些演算法各不相同,因此應根據使用情況及其安全要求選擇雜湊演算法。下面是一些應遵循的步驟:

  • 瞭解用例 – 用例決定了使用哪種演算法。例如,在儲存密碼等敏感資料時,雜湊演算法應能防止暴力攻擊。
  • 考慮你的安全要求 – 用例的安全要求取決於你打算儲存的資料型別,它們決定了要選擇什麼樣的演算法。例如,穩健的雜湊演算法最適合儲存高度敏感的資訊。
  • 研究可用的雜湊演算法 – 探索每種雜湊型別,瞭解其優缺點。這些資訊可以幫助你選擇最適合你的使用案例的選項。
  • 評估所選雜湊演算法 – 一旦選擇了雜湊演算法,就要評估它是否符合安全要求。這一過程可能包括針對已知攻擊或漏洞進行測試。
  • 實施和測試雜湊演算法 – 最後,徹底實施和測試該演算法,以確保其正確、安全地執行。

如何使用雜湊儲存密碼

雜湊技術在儲存密碼方面具有出色的潛力,而密碼是網路安全的一個重要組成部分。

理想情況下,應用程式會將密碼雜湊並儲存在安全的資料庫中,以防止未經授權的訪問和資料洩露。不過,僅靠雜湊可能不足以保護資訊。雜湊密碼仍然容易受到暴力和字典攻擊。黑客通常使用這些方法來猜測密碼,並在未經授權的情況下訪問賬戶。

使用雜湊儲存密碼的更安全方法是加鹽技術。在對密碼進行雜湊運算之前,加鹽技術會在每個密碼中新增唯一的隨機字串或字元。鹽值對每個密碼都是唯一的,應用程式會將其與雜湊密碼一起儲存在資料庫中。

每次使用者登入時,應用程式都會從資料庫中檢索鹽值,將其新增到輸入的密碼中,然後對組合後的鹽值和密碼進行雜湊。

如果攻擊者獲得了資料庫的訪問許可權,他們就必須為每個密碼和每個可能的鹽值計算雜湊值。加鹽會使這些攻擊變得更加複雜,因此是阻止字典攻擊的有效技術。

Python 的 secrets 模組讓加鹽變得簡單。該模組可生成隨機鹽,安全地儲存密碼並管理令牌和加密金鑰。

下面的程式碼使用 hashlib 庫和 secrets 模組來進一步保護使用者密碼:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import hashlib
import secrets
# Generate a random salt using the secrets module
salt = secrets.token_hex(16)
# Get the user's password from input
password = input("Enter your password: ")
# Hash the password using the salt and the SHA-256 algorithm
hash_object = hashlib.sha256((password + salt).encode())
# Get the hexadecimal representation of the hash
hash_hex = hash_object.hexdigest()
# Store the salt and hash hex in your database
import hashlib import secrets # Generate a random salt using the secrets module salt = secrets.token_hex(16) # Get the user's password from input password = input("Enter your password: ") # Hash the password using the salt and the SHA-256 algorithm hash_object = hashlib.sha256((password + salt).encode()) # Get the hexadecimal representation of the hash hash_hex = hash_object.hexdigest() # Store the salt and hash hex in your database
import hashlib
import secrets
# Generate a random salt using the secrets module
salt = secrets.token_hex(16)
# Get the user's password from input
password = input("Enter your password: ")
# Hash the password using the salt and the SHA-256 algorithm
hash_object = hashlib.sha256((password + salt).encode())
# Get the hexadecimal representation of the hash
hash_hex = hash_object.hexdigest()
# Store the salt and hash hex in your database

如何使用雜湊進行資料完整性檢查

雜湊還有助於檢查資料的完整性,保護傳輸的資料不被修改和篡改。這種四步技術使用加密雜湊函式為檔案提供唯一的雜湊值。

首先,選擇適當的雜湊函式,用它為輸入資料生成雜湊值。儲存雜湊值,然後在需要時使用它進行比較。無論何時需要驗證資料的完整性,應用程式都會使用相同的雜湊函式生成當前資料的雜湊值。然後,應用程式將新的雜湊值與儲存的值進行比較,以確保它們完全相同。如果相同,則資料未損壞。

雜湊值是唯一的,即使輸入資料發生微小的變化,也會引發明顯不同的雜湊值。這樣就很容易檢測到對傳輸資料的任何未經授權的更改或修改。

下面的步驟演示了使用雜湊函式進行資料完整性檢查。

步驟 1:匯入 hashlib 模組

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import hashlib
import hashlib
import hashlib

步驟 2:使用雜湊演算法

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
def generate_hash(file_path):
# Open the file in binary mode
with open(file_path, "rb") as f:
# Read the contents of the file
contents = f.read()
# Generate the SHA-256 hash of the contents
hash_object = hashlib.sha256(contents)
# Return the hexadecimal representation of the hash
return hash_object.hexdigest()
def generate_hash(file_path): # Open the file in binary mode with open(file_path, "rb") as f: # Read the contents of the file contents = f.read() # Generate the SHA-256 hash of the contents hash_object = hashlib.sha256(contents) # Return the hexadecimal representation of the hash return hash_object.hexdigest()
def generate_hash(file_path):
# Open the file in binary mode
with open(file_path, "rb") as f:
# Read the contents of the file
contents = f.read()
# Generate the SHA-256 hash of the contents
hash_object = hashlib.sha256(contents)
# Return the hexadecimal representation of the hash
return hash_object.hexdigest()

步驟 3:呼叫函式並輸入檔案路徑

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
file_path = "path/to/my/file.txt"
hash_value = generate_hash(file_path)
print(hash_value)
file_path = "path/to/my/file.txt" hash_value = generate_hash(file_path) print(hash_value)
file_path = "path/to/my/file.txt"
hash_value = generate_hash(file_path)
print(hash_value)

步驟 4:生成原始檔案和已傳輸或修改檔案的雜湊值

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
# Generate the hash of the original file
original_file_path = "path/to/my/file.txt"
original_file_hash = generate_hash(original_file_path)
# Transmit or modify the file (for example, by copying it to a different location)
transmitted_file_path = "path/to/transmitted/file.txt"
# Generate the hash of the transmitted file
transmitted_file_hash = generate_hash(transmitted_file_path)
# Generate the hash of the original file original_file_path = "path/to/my/file.txt" original_file_hash = generate_hash(original_file_path) # Transmit or modify the file (for example, by copying it to a different location) transmitted_file_path = "path/to/transmitted/file.txt" # Generate the hash of the transmitted file transmitted_file_hash = generate_hash(transmitted_file_path)
# Generate the hash of the original file
original_file_path = "path/to/my/file.txt"
original_file_hash = generate_hash(original_file_path)
# Transmit or modify the file (for example, by copying it to a different location)
transmitted_file_path = "path/to/transmitted/file.txt"
# Generate the hash of the transmitted file
transmitted_file_hash = generate_hash(transmitted_file_path)

步驟 5:比較兩個雜湊值

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
if original_file_hash == transmitted_file_hash:
print("The file has not been tampered with")
else:
print("The file has been tampered with")
if original_file_hash == transmitted_file_hash: print("The file has not been tampered with") else: print("The file has been tampered with")
if original_file_hash == transmitted_file_hash:
print("The file has not been tampered with")
else:
print("The file has been tampered with")

小結

雜湊對於資料完整性和密碼安全非常重要。使用安全的雜湊技術(如使用 hashlib 模組和加鹽)可以最大限度地利用雜湊函式。

這些技術有助於防止彩虹攻擊、碰撞攻擊和其他影響雜湊的安全漏洞。程式設計師經常將這些技術與 Python 中的雜湊函式一起使用,以確保檔案的資料完整性和密碼的安全儲存。

評論留言