Python經常使用模塊之hashlib模塊

1.hashilib模塊的功能

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

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

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

    摘要算法之因此能指出數據是否被篡改過,就是由於摘要函數是一個單向函數,計算data的摘要digest很容易,可是經過digest反推data卻很是困難,並且,對原始數據作一個bit的修改,都會致使據算出的摘要徹底不一樣。app

 2.如何使用hashilib模塊。

    使用hashilib模塊通常分爲4步:運維

    (1)在python中引用hashlib模塊。函數

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

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

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

 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.注意事項

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

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

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

7.當要加密的數據量很大時,能夠分塊屢次調用update(),最後計算的結果是同樣的。

import hashlib  #調用hashlib模塊
md5 = hashlib.md5()  #建立一個md5模塊
md5.update("how to use md5 in ".encode("utf-8"))  #調用md5的update()方法,對參數進行加密,加密必須爲bytes類型
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 密碼驗證

全部容許用戶登陸的網站都會將用戶登陸的用戶名和密碼存儲在數據庫中。

name | password --------+---------- michael | 123456 bob | abc999 alice | alice2008

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

username | password ---------+--------------------------------- michael | e10adc3949ba59abbe56e057f20f883e bob | 878ef96e86145580c38c87f0410ad153 alice | 99b1c2188db85afee403b1536010c2c9

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("abd", 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表示註冊").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("輸入不合法")

  

相關文章
相關標籤/搜索