hashlib模塊學習

1 hashilib模塊的功能

python的hashlib提供了常見的摘要算法,如MD5、SHA1等等。

什麼是摘要算法呢?

摘要算法又稱哈希算法、散列算法。它通過一個函數,把任意長度的數據轉換成一個長度固定的數據串(通常用16進制的字符串表示)。

摘要算法就是通過摘要函數對任意長度的data計算出固定長度的摘要digest,目的是爲了發現原始數據是否被人篡改過

摘要算法之所以能指出數據是否被篡改過,就是因爲摘要函數是一個單向函數,計算data的摘要digest很容易,但是通過digest反推data卻非常困難,而且,對原始數據做一個bit的修改,都會導致據算出的摘要完全不同。

2 如何使用hashilib模塊

使用hashilib模塊一般分爲4步:

1)在python中引用hashlib模塊。

2)創建一個hash對象,使用hash算法命名的構造函數,或者通用構造函數。

3)使用hash對象調用update()方法填充對象

4)調用digest()或者hexdigest()方法來獲取摘要(加密結果)

3 實例代碼

import hashlib

s = "How to use md5 in python hashlib?"
md5 = hashlib.md5()  # 調用一個 md5對象
# 調用md5的update()方法,對參數進行加密,加密必須爲bytes類型
md5.update(s.encode("utf-8"))
print(md5.hexdigest())  # 打印加密結果

運行結果:

4 hashlib的常用代碼

4.1 md5 = hashlib.md5() 或 md5 = hashlib.new("md5")

md5可以替換爲其他的哈希類型。

4.2 md5.update(arg)

將字節對象arg填充到hashlib對象中,arg通常爲要加密的字符串

4.3 md5.digest()

返回加密結果,它是一個字節對象,長度爲md5.digest_size

4.4 md5.hexdigest()

返回加密結果,它是一個字符串對象,長度爲md5.digest_size*2,只包含16進制數字。

5 hashlib模塊提供的常量屬性

5.1 hashlib.algorithms_guaranteed

獲取保證在所有平臺上此模塊支持的hash算法名稱的集合。

5.2 hashlib.algorithms_available

獲取可以運行在python解釋器中的hash算法名稱的集合。

6 注意事項

1update()方法需要接收的參數是一個字節對象。

2)常用的一些算法主要有sha1, sha224, sha256, sha384, sha512, md5等算法。

3sha1算法比較早,是不能暴力破解的。

7.當要加密的數據量很大時,可以分塊多次調用update(),最後計算的結果是一樣的

import hashlib  # 調用hashlib模塊

# s = "How to use md5 in python hashlib?"
# 創建一個md5模塊
md5 = hashlib.md5()
# 調用md5的update()方法,對參數進行加密,加密必須爲bytes類型
md5.update("How to use md5 in ".encode("utf-8"))
md5.update("python hashlib?".encode("utf-8"))
print(md5.hexdigest())  # 獲取摘要內容

運行結果:

8 sha1摘要算法

sha1摘要算法是另一種常見的摘要算法,調用sha1的方式和md5類似

import hashlib

sha1 = hashlib.sha1()
sha1.update("how to use sha1 in ".encode("utf-8"))
sha1.update("python hashlib?".encode("utf-8"))
print(sha1.hexdigest())

運行結果:

9 hashlib的應用

9.1 密碼驗證

所有允許用戶登錄的網站都會將用戶登錄的用戶名和密碼存儲在數據庫中。

如果以明文保存用戶口令,如果數據庫泄漏,所有用戶的口令就落入黑客的手中。此外,網站運維人員是可以訪問數據庫的,也可以獲取到所有用戶的口令。正確的把保存口令的方式不是存儲用戶的明文密碼,而是存儲用戶密碼的摘要,比如md5

9.2  文件校驗

hashlib的還有一個方面的應用就是文件校驗,它可以在文件傳輸時,驗證文件是否被完整接收,這用到的是hashlib的“相同字符串的摘要一致”原理。如果摘要一致,說明文件傳輸完成,否則就是文件在傳輸過程中丟幀。

10 加鹽

考慮到有這個一個情況,就是有些用戶喜歡用“123456”、“888888”等一些簡單的口令,於是,黑客可以事先計算出這些常見口令的md5值,得到一個反推表:

'e10adc3949ba59abbe56e057f20f883e': '123456'
'21218cca77804d2ba1922c33e0151105': '888888'

這樣,無需破解,只需要對比數據庫的md5,黑客就獲得了使用常用口令的用戶帳號。

對於用戶來說,當然不要使用過於簡單的口令。同時,我們在程序設計上對簡單口令加強保護。

由於常用口令的md5值很容易被計算出來,所以,要確保存儲的用戶密碼不是那些已經被計算出來的常用口令的md5。這一方法通過對原始口令加一個複雜字符串來實現,俗成“加鹽”:

hashlib.md5("salt".encode("utf-8"))

經過“salt”處理的md5口令,只要“salt”不被黑客知道,即使用戶輸入簡單口令,也很難通過md5反推明文口令。

但是如果有兩個用戶都使用了相同的簡單密碼,比如“123456”,在數據庫中,將存儲兩條相同的md5值,這說明兩個用戶的密碼是一樣的。

那麼,有沒有辦法讓使用相同口令的用戶存儲不同的md5呢?

假定用戶無法修改登錄名,就可以通過把登錄名作爲“salt”的一部分來計算md5,從而實現相同口令的用戶也存儲相同的md5。

11 hashlib模塊補充

摘要算法在很多地方都有廣泛的應用,要注意摘要算法不是加密算法,不能用於加密(因爲無法通過摘要反推明文),只能用於防篡改,但是他的單向計算特性決定了可以在不存儲明文密碼的情況下驗證用戶口令。

12 一個簡單的驗證存儲明文口令程序

import hashlib


def md5(arg):
    """這是加密函數,將傳進來的函數加密"""
    # 加鹽
    md5_pwd = hashlib.md5(bytes("salt", encoding="utf-8"))
    md5_pwd.update(bytes(arg, encoding="utf-8"))
    return md5_pwd.hexdigest()  # 返回加密的數據


def log(user, pwd):  # 登錄時候的函數,由於md5不能反解, 因此登錄的時候用正解
    with open("user.txt", mode="r", encoding="utf-8") as f:
        for line in f:
            name, password = line.strip().split("|")
            # 登錄的時候驗證用戶名以及加密的密碼跟之前保存的是否一樣
            if user == name and password == md5(pwd):
                return True


def register(user, pwd):  # 註冊的時候把用戶名和加密的密碼寫進文件,保存起來
    with open("user.txt", mode="a", encoding="utf-8") as f:
        msg = user + "|" + md5(pwd) + "\n"
        f.write(msg)


i = input("1表示登錄,2表示註冊\n請選擇:").strip()
if i == "2":
    user = input("用戶名:")
    pwd = input("密碼:")
    register(user, pwd)
elif i == "1":
    user = input("用戶名:")
    pwd = input("密碼:")
    r = log(user, pwd)  # 驗證用戶名和密碼
    if r == True:
        print("登錄成功")
    else:
        print("登錄失敗")
else:
    print("輸入不合法")
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章