Python學(xué)習(xí)之加密模塊使用詳解
hashlib 模塊
hashlib 模塊的介紹
hashlib 模塊中擁有很多的加密算法,我們并不需要關(guān)心加密算法的實(shí)現(xiàn)方法。只需要調(diào)用我們需要的加密函數(shù),就可以幫助我們對(duì)數(shù)據(jù)進(jìn)行加密。
它的加密算法有很多,不僅如此,hashlib 中很多加密算法加密難度很大,所以加密后的數(shù)據(jù)很難被破解(這里的很難被破解是相對(duì)而言的,比如MD5、sha1、mysql、ntlm就可以在 cmd5 通過(guò)窮舉的方式進(jìn)行明密文的對(duì)應(yīng)查詢(xún)。),這就是 hashlib 強(qiáng)大的地方。既然無(wú)法破解也就無(wú)法解密,所以hashlib 中的加密方法都是不可逆的。
hashlib 模塊中的常用加密方法
接下來(lái)就讓我們看一下 hashlib 中常用的加密算法:
| 函數(shù)名 | 參數(shù) | 介紹 | 舉例 | 返回值 |
|---|---|---|---|---|
| md5 | byte | md5算法加密 | hashlib.md5(b’hello’) | hash對(duì)象 |
| sha1 | byte | sha1算法加密 | hashlib.sha1(b’hello’) | hash對(duì)象 |
| sha256 | byte | sha256算法加密 | hashlib.sha256(b’hello’) | hash對(duì)象 |
| sha512 | byte | sha512算法加密 | hashlib.512(b’hello’) | hash對(duì)象 |
以上的加密函數(shù)都有一個(gè) byte 類(lèi)型的參數(shù),通過(guò)調(diào)用對(duì)應(yīng)的函數(shù)會(huì)返回一個(gè) hash對(duì)象。所謂 hashlib 就是一種加密方式。
sha1、sha256、sha512 的區(qū)別就是 數(shù)值越高,被破解的概率就越低。
hashlib 模塊生成加密字符串示例:
import hashlib hashobj = hashlib.md5(b'Hello_World') # 將 'Hello_World'以 byte 形式傳入,通過(guò) md5 加密 賦值給 hashobj 對(duì)象 result = hashobj.hexdigest() # hashobj 通過(guò) hexdigest() 函數(shù)的16進(jìn)制生成加密字符串賦值給 result print(result) # >>> 執(zhí)行結(jié)果如下: # >>> 486b98e454e54f44e811b9c62857f8f7
hashlib模塊情景練習(xí)
大家可能有一個(gè)疑問(wèn), hashlib 模塊加密后的無(wú)法解密獲取原始數(shù)據(jù),那我們加密后的信息有什么用呢?實(shí)際上場(chǎng)景有很多,我們今天就來(lái)舉例一個(gè)場(chǎng)景。
比如我們的用戶(hù)需要某一個(gè)服務(wù)的幫助,用戶(hù)每次請(qǐng)求服務(wù)都需要一個(gè)憑證。這個(gè)憑證信息是通過(guò)加密的方式生成的字符串,并且該加密方式是雙方達(dá)成一致,標(biāo)準(zhǔn)相同的。當(dāng)用戶(hù)請(qǐng)求該服務(wù)的時(shí)候,帶上這個(gè)加密的字符串,服務(wù)會(huì)通過(guò)響應(yīng)的加密規(guī)范也生成一個(gè)字符串。如果用戶(hù)帶過(guò)來(lái)的憑證的字符串與服務(wù)計(jì)算出來(lái)的憑證的字符串完全一致,則證明用戶(hù)請(qǐng)求的這個(gè)服務(wù)是一個(gè)合法的請(qǐng)求,反之則不合法。
那么定義這樣一個(gè)認(rèn)證簽名字符串就需要兩個(gè)數(shù)據(jù)和一個(gè)模塊,模塊就是 hashlib ,數(shù)據(jù)1就是 用戶(hù)與服務(wù)之間達(dá)成共識(shí)的一個(gè)基礎(chǔ)簽名 ,我們定義它為 bash_sign ;數(shù)據(jù)2我們可以使用 用戶(hù)請(qǐng)求服務(wù)生成憑證的時(shí)間戳,我們定義它為 user_timestamp 。
代碼示例如下:
# coding:utf-8
import hashlib
import time
bash_sign = 'signature' # 定義一個(gè)基礎(chǔ)簽名變量
def user_request_client(): # TODO 用戶(hù)簽名
user_time = int(time.time()) # 獲取用戶(hù)請(qǐng)求服務(wù)生成憑證的時(shí)間戳 ;python 的時(shí)間戳是浮點(diǎn)類(lèi)型,這里轉(zhuǎn)成整型。
_token = '%s%s' % (bash_sign, user_time) # 定義一個(gè)加密之前的token,將 bash_sign 與 user_time 傳入
hashobj = hashlib.sha1(_token.encode('utf-8')) # 由于參數(shù)是 byte 類(lèi)型,所以我們需要將 _token 進(jìn)行編碼
user_token = hashobj.hexdigest() # 將 bash_sign 與 user_time 通過(guò) sha1 加密的字符串 賦值給 user_token
return user_token, user_time
def service_check_token(token, user_timestamp): # TODO 服務(wù)器校驗(yàn)簽名
_token = '%s%s' % (bash_sign, user_timestamp) # 服務(wù)器接收用戶(hù)請(qǐng)求傳入的 token 與 時(shí)間戳
service_token = hashlib.sha1(_token.encode('utf-8')).hexdigest() # 服務(wù)器的 token ,加密方式與用戶(hù)請(qǐng)求加密方式一致
if token == service_token: # 校驗(yàn)加密串的合法性,若校驗(yàn)不通過(guò),拒絕用戶(hù)的服務(wù)請(qǐng)求
# print(token, '---', user_timestamp)
return True
else:
return False
if __name__ == '__main__':
need_help_token, timestamp = user_request_client()
# time.sleep(1) # 取消注釋后,時(shí)間錯(cuò)不一致則會(huì) 簽名校驗(yàn)不通過(guò)
# result = service_check_token(need_help_token, time.time())
result = service_check_token(need_help_token, timestamp)
if result == True:
print('用戶(hù)請(qǐng)求服務(wù)簽名校驗(yàn)通過(guò),服務(wù)器提供對(duì)應(yīng)服務(wù)')
else:
print('用戶(hù)請(qǐng)求服務(wù)簽名校驗(yàn)未通過(guò),服務(wù)器拒絕提供對(duì)應(yīng)服務(wù)')
# >>> 執(zhí)行結(jié)果如下:
# >>> 用戶(hù)請(qǐng)求服務(wù)簽名校驗(yàn)通過(guò),服務(wù)器提供對(duì)應(yīng)服務(wù)
所以這一種驗(yàn)證需要兩個(gè)方面,第一個(gè)就是我們生成傳入的 token 以及 時(shí)間戳,第二個(gè)就是 token 是否是按照我們定義好的標(biāo)準(zhǔn)生成的;
這兩個(gè)不管是那一個(gè)出錯(cuò)了,服務(wù)器校驗(yàn)簽名都是不通過(guò)。這也是 hashlib 模塊 常用的場(chǎng)景之一,大家也可以嘗試拓展一下思維,還有哪些場(chǎng)景適用于這種不可逆的算法。
base64 模塊
base64 模塊的介紹
base64 加密模塊也是一種通用型的加密算法,與之前我們講的 json 模塊一樣,在很多編程語(yǔ)言中都有 base64模塊且功能基本相同。 所以在任何編程語(yǔ)言中,都可以將base64加密的字符串進(jìn)行解密。
既然都可以進(jìn)行解密,那么帶來(lái)的問(wèn)題就是沒(méi)有安全可言了。其實(shí)不然,我們自然有辦法去解決。稍后我們通過(guò)一個(gè)小練習(xí)來(lái)解決這個(gè)問(wèn)題。
base64 模塊 模塊中的常用方法
| 函數(shù)名 | 參數(shù) | 介紹 | 舉例 | 返回值 |
|---|---|---|---|---|
| encodestring | byte | 進(jìn)行base64加密 | base64.encodestring(b’string’) | byte |
| decodestring | byte | 進(jìn)行base64解密 | base64.decodestring(b’c3RyaW5n\n’) | byte |
| encodebytes | byte | 進(jìn)行base64加密 | base64.encodebytes(b’string’) | byte |
| decodebytes | byte | 進(jìn)行base64解密 | base64.decodebytes(b’c3RyaW5n\n’) | byte |
注意:encodestring()函數(shù) 與 decodestring() 函數(shù) 雖然從名字上來(lái)看是對(duì) 字符串 進(jìn)行 加密解密,但是在用法上需要對(duì)字符串進(jìn)行 byte 類(lèi)型的轉(zhuǎn)換,然后再執(zhí)行對(duì)應(yīng)的加密解密操作。
encodebytes()函數(shù) 與 decodebytes() 函數(shù) 功能、參數(shù)、返回值 與字符串加解密一致,實(shí)際上在 python3.x 中,官方更推薦使用著一組函數(shù)進(jìn)行加密和解密。
base64 模塊的情景練習(xí)
接下來(lái)我們看一下 base64 模塊的 加解密演示那里:
注意:由于無(wú)論如何我們都需要通過(guò) byte 類(lèi)型進(jìn)行數(shù)據(jù)的加密與解密,所以我們可以對(duì)加密、解密進(jìn)行一個(gè)封裝。
# coding:utf-8
import base64
def encode(data): # 編碼函數(shù)
if isinstance(data, str): # 判斷傳入的 data 的數(shù)據(jù)類(lèi)型
data = data.encode('utf-8')
elif isinstance(data, bytes):
data = data
else:
raise TypeError('傳輸?shù)?\'data\' 參數(shù)需為 bytes 或 str 類(lèi)型')
# print(base64.encodebytes(data))
# print(base64.encodebytes(data).decode('utf-8'))
return base64.encodebytes(data).decode('utf-8') # 加密后的 data 格式為byte類(lèi)型,需要進(jìn)行解碼為字符串,參考上兩行代碼
def decone(data):
if not isinstance(data, bytes):
raise TypeError('傳輸?shù)?\'data\' 參數(shù)需為 bytes 類(lèi)型')
return base64.decodebytes(data).decode('utf-8')
if __name__ == '__main__':
result = encode('signature')
print('base64 編碼后的結(jié)果為:', result)
new_result = decone(result.encode('utf-8'))
print('base64 解碼后的結(jié)果為:', new_result)
# >>> 執(zhí)行結(jié)果如下:
# >>> base64 編碼后的結(jié)果為: c2lnbmF0dXJl
# >>> base64 解碼后的結(jié)果為: signature
但是就像上文我們提及的一樣,既然所有人都知道 base64 的加密方式與解密方式,那我們?cè)撊绾问呛媚??其?shí)也很簡(jiǎn)單,那就是對(duì)我們的 base64 加密的密文進(jìn)行字符串替換的二次輸出。(所謂的二次輸出,其實(shí)就是二次轉(zhuǎn)換的過(guò)程。)
比如我們定義三個(gè)字符串專(zhuān)門(mén)用作加密后的某個(gè)字符的替換,代碼示例如下:
# coding:utf-8
import base64
replace_one = '$'
replace_two = '%'
replace_three = '='
def encode(data): # 編碼函數(shù)
if isinstance(data, str): # 判斷傳入的 data 的數(shù)據(jù)類(lèi)型
data = data.encode('utf-8')
elif isinstance(data, bytes):
data = data
else:
raise TypeError('傳輸?shù)?\'data\' 參數(shù)需為 bytes 或 str 類(lèi)型')
# print(base64.encodebytes(data))
# print(base64.encodebytes(data).decode('utf-8'))
_data = base64.encodebytes(data).decode('utf-8') # 加密后的 data 格式為byte類(lèi)型,需要進(jìn)行解碼為字符串,參考上兩行代碼
_data = _data.replace('c', replace_one).replace('2', replace_two).replace('l', replace_three) # 替換 'c'、'2'、'l'
return _data
def decone(data):
if not isinstance(data, bytes):
raise TypeError('傳輸?shù)?\'data\' 參數(shù)需為 bytes 類(lèi)型')
return base64.decodebytes(data).decode('utf-8')
if __name__ == '__main__':
result = encode('signature')
print('base64 編碼后的結(jié)果為:', result)
new_result = decone(result.encode('utf-8'))
print('base64 解碼后的結(jié)果為:', new_result)
執(zhí)行結(jié)果如下:

既然加密進(jìn)行了二次轉(zhuǎn)換,那么解密的時(shí)候同樣需要進(jìn)行二次轉(zhuǎn)換才行,所以我們需要重構(gòu)一下 decone() 函數(shù)。
def decone(data):
if not isinstance(data, bytes):
raise TypeError('傳輸?shù)?\'data\' 參數(shù)需為 bytes 類(lèi)型')
replace_one_decone = replace_one.encode('utf-8') # 需要將二次轉(zhuǎn)換的變量已 byte 的形式進(jìn)行解碼
replace_two_decone = replace_two.encode('utf-8')
replace_three_decone = replace_three.encode('utf-8')
data = data.replace(replace_one_decone, b'c').replace(replace_two_decone, b'2').replace(replace_three_decone, b'l')
return base64.decodebytes(data).decode('utf-8')
運(yùn)行結(jié)果如下:

小節(jié):通過(guò)這種方法,只有具體的開(kāi)發(fā)人員與使用的業(yè)務(wù)人員才知道這種二次替換的方式,需要通過(guò)那些字符進(jìn)行加密或者解密。從而提高了數(shù)據(jù)傳輸?shù)陌踩浴?/p>
到此這篇關(guān)于Python學(xué)習(xí)之加密模塊使用詳解的文章就介紹到這了,更多相關(guān)Python加密模塊內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python Mysql數(shù)據(jù)庫(kù)操作 Perl操作Mysql數(shù)據(jù)庫(kù)
python對(duì)mysql數(shù)據(jù)庫(kù)的一些操作實(shí)現(xiàn)代碼2009-01-01
Python實(shí)現(xiàn)采用進(jìn)度條實(shí)時(shí)顯示處理進(jìn)度的方法
這篇文章主要介紹了Python實(shí)現(xiàn)采用進(jìn)度條實(shí)時(shí)顯示處理進(jìn)度的方法,涉及Python數(shù)學(xué)運(yùn)算結(jié)合時(shí)間函數(shù)顯示進(jìn)度效果的相關(guān)操作技巧,需要的朋友可以參考下2017-12-12
使用python實(shí)現(xiàn)多維數(shù)據(jù)降維操作
今天小編就為大家分享一篇使用python實(shí)現(xiàn)多維數(shù)據(jù)降維操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-02-02
TensorFlow實(shí)現(xiàn)AutoEncoder自編碼器
這篇文章主要為大家詳細(xì)介紹了TensorFlow實(shí)現(xiàn)AutoEncoder自編碼器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03
python實(shí)現(xiàn)的自動(dòng)發(fā)送消息功能詳解
這篇文章主要介紹了python實(shí)現(xiàn)的自動(dòng)發(fā)送消息功能,涉及Python基于requests、itchat庫(kù)的數(shù)據(jù)請(qǐng)求與信息處理相關(guān)操作技巧,需要的朋友可以參考下2019-08-08
使用Python實(shí)現(xiàn)調(diào)整Excel中的行列順序
調(diào)整Excel?行列順序指的是改變工作表中行或列的位置,以便更好地展示和分析數(shù)據(jù),本文將介紹如何通過(guò)Python高效地調(diào)整Excel?行列順序,感興趣的可以了解下2025-01-01

