前言 - Prologue
hashlib 是 Python 中的一個標準模組,用於計算資料的 hash 值 (雜湊值/哈希值)。Hash 值是一個固定長度的二進制資料,通常是一個字串,可以用來代表原始資料,或是用於資料的完整性驗證、加密等場景。
正文 - Main text
hashlib 模組提供了多種 hash 演算法,包括常見的 MD5 和 SHA 系列演算法。使用 hashlib 模組計算 hash 值通常的流程如下:
- 創建一個 hashlib 對象,指定要使用的 hash 演算法。
- 將要計算 hash 值的資料逐個塊讀入,使用
update()
方法更新 hashlib 對象。
- 使用
digest()
或 hexdigest()
方法得到最終的 hash 值,分別以二進制和十六進制表示。
常見的 Hash 演算法
MD5 演算法
MD5 的全名是 Message-Digest Algorithm 5,中文名稱為「訊息摘要演算法」,是一種常見的 hash 函數演算法。
能夠將任意長度的資料轉換為一個固定長度 (128 bits
) 的 hash 值,通常以 32
個十六進制的形式表示,常用於檢查資料的完整性以及確認資料在傳輸過程中是否被篡改。
雖然此演算法已被廣泛使用,但因為其安全性問題,現在已經不再推薦使用。
import hashlib
string = "Hello, world!"
hash_object = hashlib.md5(string.encode())
hex_dig = hash_object.hexdigest()
print(hex_dig)
SHA 系列演算法
SHA 的全名是 Secure Hash Algorithm,中文名稱為「安全雜湊演算法」,是一個系列的 hash 函數演算法,由美國國家安全局(NSA)設計,比 MD5 更安全的 hash 演算法,現在仍然被廣泛使用。
SHA-1 是第一個被廣泛使用的 SHA 演算法,能夠將任意長度的資料轉換為一個固定長度 (160 bits
) 的 hash 值。常用於資料完整性驗證和加密,例如:SSL 通訊協議中的數字簽名。
然而由於 SHA-1 存在安全漏洞,現在已經不再安全,因此 SHA-2 和 SHA-3 逐漸取代了 SHA-1。
版本有很多種,其中比較常見的有 SHA-1、SHA-256、SHA-384 和 SHA-512。
- SHA-1 可計算出一個
160
位的 hash 值,通常以 40
個十六進制的形式表示。
- SHA-256 可計算出一個
256
位的 hash 值,通常以 64
個十六進制的形式表示。
- SHA-384 可計算出一個
384
位的 hash 值,通常以 96
個十六進制的形式表示。
- SHA-512 可計算出一個
512
位的 hash 值,通常以 128
個十六進制的形式表示。
import hashlib
string = "Hello, world!"
hash_object = hashlib.sha256(string.encode())
hex_dig = hash_object.hexdigest()
print(hex_dig)
其他演算法
除了 MD5 和 SHA 演算法之外,hashlib 模組還提供了其他一些 hash 演算法,例如 SHA3、blake2 等。
使用方法和上面介紹的演算法類似,只需要在創建 hashlib 對象時指定要使用的演算法即可。
優缺點
Hash 演算法的優點是:
- 可將任意長度的資料轉換成固定長度的 hash 值,方便存儲和比較。
- 計算速度非常快,通常只需要幾個時鐘週期就可以完成。
- Hash 值是不可逆的,即無法根據 hash 值推算出原始資料,保護了資料的安全性。
- 雜湊結果非常敏感,即原始資料的微小變化都會導致 hash 值的大幅度變化,用於資料的完整性校驗和防止資料被篡改。
- 碰撞機率極低,即兩個不同的原始資料的 hash 值相同的概率極小,這保證了 hash 值的唯一性,防止了不同的資料產生相同的 hash 值。
Hash 演算法的缺點是:
- Hash 值是固定長度的,如果原始資料的長度非常大,則 hash 值可能會出現碰撞,即不同的原始資料產生相同的 hash 值。
- 因為 hash 值是不可逆的,所以無法從 hash 值反推出原始資料,不適用於加密和解密操作。
- 一些常用的 hash 演算法(例如 MD5)已經被發現存在安全漏洞,這使得這些演算法不再適用於安全應用。因此,在選擇 hash 演算法時需要仔細考慮其安全性。
特徵
剛剛上面所介紹的優缺點中的優點總結為特徵為:
- 將任意長度的輸入轉換為固定長度的輸出
- 快速計算
- 不可逆轉
- 雜湊結果敏感
- 碰撞機率極小
Hash 函數
hashlib.md5()
: 計算傳入資料的 MD5 hash 值。
hashlib.sha1()
: 計算傳入資料的 SHA1 hash 值。
hashlib.sha256()
: 計算傳入資料的 SHA256 hash 值。
update()
: 更新 hash 物件的資料內容,可多次調用。
digest()
: 返回已更新資料的 hash 值,返回的是二進制。
hexdigest()
: 返回已更新資料的 hash 值,返回的是十六進制。
除了以上常見的 hash 函數外,還有其他的 hash 函數,例如 SHA-512、BLAKE2、Whirlpool 等等。hash 函數的具體實現方式和內部細節可能有所不同,但它們都具有將任意長度的資料轉換成固定長度的 hash 值的功能,並且具有快速計算、不可逆、敏感性、低碰撞概率等特點。
其他補充
雖然 Python 提供了 hashlib 模組進行多種 hash 演算法的計算,例如:MD5、SHA1、SHA256 等。這些演算法雖然很多,但只限於目前的系統使用。
如果要發展跨平台的程式,應該要以跨平台通用的 hash 演算法為主。這些跨平台的演算法可以透過使用 hashlib.algorithms_guaranteed
屬性查詢,而 hashlib.algorithms_available
屬性則會列出目前平台上可用的所有 hash 演算法。
import hashlib
print(hashlib.algorithms_available)
print(hashlib.algorithms_guaranteed)
執行以上程式碼後,可以得到相關的 hash 演算法清單。根據需要選擇合適的演算法,並進行相應的加密或驗證操作。
詳情還是要參考官方文件:
hashlib.algorithms_guaranteed
A set containing the names of the hash algorithms guaranteed to be supported by this module on all platforms. Note that ‘md5’ is in this list despite some upstream vendors offering an odd “FIPS compliant” Python build that excludes it.
New in version 3.2.
hashlib.algorithms_available
A set containing the names of the hash algorithms that are available in the running Python interpreter. These names will be recognized when passed to new(). algorithms_guaranteed will always be a subset. The same algorithm may appear multiple times in this set under different names (thanks to OpenSSL).
New in version 3.2.
參考資料 - Reference
[1] hashlib — Secure hashes and message digests — Python 3.11.2 documentation
https://docs.python.org/3/library/hashlib.html
後記 - Epilogue
先前幫認識的學長教了一下他弟弟的 Python 作業做的小筆記轉化成部落格文章(?)。