網(wǎng)站首頁 編程語言 正文
hashlib 模塊
hashlib 模塊的介紹
hashlib 模塊中擁有很多的加密算法,我們并不需要關(guān)心加密算法的實現(xiàn)方法。只需要調(diào)用我們需要的加密函數(shù),就可以幫助我們對數(shù)據(jù)進行加密。
它的加密算法有很多,不僅如此,hashlib 中很多加密算法加密難度很大,所以加密后的數(shù)據(jù)很難被破解(這里的很難被破解是相對而言的,比如MD5、sha1、mysql、ntlm就可以在 cmd5 通過窮舉的方式進行明密文的對應查詢。),這就是 hashlib 強大的地方。既然無法破解也就無法解密,所以hashlib 中的加密方法都是不可逆的。
hashlib 模塊中的常用加密方法
接下來就讓我們看一下 hashlib 中常用的加密算法:
函數(shù)名 | 參數(shù) | 介紹 | 舉例 | 返回值 |
---|---|---|---|---|
md5 | byte | md5算法加密 | hashlib.md5(b’hello’) | hash對象 |
sha1 | byte | sha1算法加密 | hashlib.sha1(b’hello’) | hash對象 |
sha256 | byte | sha256算法加密 | hashlib.sha256(b’hello’)? | hash對象 |
sha512 | byte | sha512算法加密 | hashlib.512(b’hello’)? | hash對象 |
以上的加密函數(shù)都有一個 byte 類型的參數(shù),通過調(diào)用對應的函數(shù)會返回一個 hash對象。所謂 hashlib 就是一種加密方式。
sha1、sha256、sha512 的區(qū)別就是 數(shù)值越高,被破解的概率就越低。
hashlib 模塊生成加密字符串示例:
import hashlib hashobj = hashlib.md5(b'Hello_World') # 將 'Hello_World'以 byte 形式傳入,通過 md5 加密 賦值給 hashobj 對象 result = hashobj.hexdigest() # hashobj 通過 hexdigest() 函數(shù)的16進制生成加密字符串賦值給 result print(result) # >>> 執(zhí)行結(jié)果如下: # >>> 486b98e454e54f44e811b9c62857f8f7
hashlib模塊情景練習
大家可能有一個疑問, hashlib 模塊加密后的無法解密獲取原始數(shù)據(jù),那我們加密后的信息有什么用呢?實際上場景有很多,我們今天就來舉例一個場景。
比如我們的用戶需要某一個服務的幫助,用戶每次請求服務都需要一個憑證。這個憑證信息是通過加密的方式生成的字符串,并且該加密方式是雙方達成一致,標準相同的。當用戶請求該服務的時候,帶上這個加密的字符串,服務會通過響應的加密規(guī)范也生成一個字符串。如果用戶帶過來的憑證的字符串與服務計算出來的憑證的字符串完全一致,則證明用戶請求的這個服務是一個合法的請求,反之則不合法。
那么定義這樣一個認證簽名字符串就需要兩個數(shù)據(jù)和一個模塊,模塊就是 hashlib ,數(shù)據(jù)1就是 用戶與服務之間達成共識的一個基礎(chǔ)簽名 ,我們定義它為 bash_sign ;數(shù)據(jù)2我們可以使用 用戶請求服務生成憑證的時間戳,我們定義它為 user_timestamp 。
代碼示例如下:
# coding:utf-8 import hashlib import time bash_sign = 'signature' # 定義一個基礎(chǔ)簽名變量 def user_request_client(): # TODO 用戶簽名 user_time = int(time.time()) # 獲取用戶請求服務生成憑證的時間戳 ;python 的時間戳是浮點類型,這里轉(zhuǎn)成整型。 _token = '%s%s' % (bash_sign, user_time) # 定義一個加密之前的token,將 bash_sign 與 user_time 傳入 hashobj = hashlib.sha1(_token.encode('utf-8')) # 由于參數(shù)是 byte 類型,所以我們需要將 _token 進行編碼 user_token = hashobj.hexdigest() # 將 bash_sign 與 user_time 通過 sha1 加密的字符串 賦值給 user_token return user_token, user_time def service_check_token(token, user_timestamp): # TODO 服務器校驗簽名 _token = '%s%s' % (bash_sign, user_timestamp) # 服務器接收用戶請求傳入的 token 與 時間戳 service_token = hashlib.sha1(_token.encode('utf-8')).hexdigest() # 服務器的 token ,加密方式與用戶請求加密方式一致 if token == service_token: # 校驗加密串的合法性,若校驗不通過,拒絕用戶的服務請求 # print(token, '---', user_timestamp) return True else: return False if __name__ == '__main__': need_help_token, timestamp = user_request_client() # time.sleep(1) # 取消注釋后,時間錯不一致則會 簽名校驗不通過 # result = service_check_token(need_help_token, time.time()) result = service_check_token(need_help_token, timestamp) if result == True: print('用戶請求服務簽名校驗通過,服務器提供對應服務') else: print('用戶請求服務簽名校驗未通過,服務器拒絕提供對應服務') # >>> 執(zhí)行結(jié)果如下: # >>> 用戶請求服務簽名校驗通過,服務器提供對應服務
所以這一種驗證需要兩個方面,第一個就是我們生成傳入的 token 以及 時間戳,第二個就是 token 是否是按照我們定義好的標準生成的;
這兩個不管是那一個出錯了,服務器校驗簽名都是不通過。這也是 hashlib 模塊 常用的場景之一,大家也可以嘗試拓展一下思維,還有哪些場景適用于這種不可逆的算法。
base64 模塊
base64 模塊的介紹
base64 加密模塊也是一種通用型的加密算法,與之前我們講的 json 模塊一樣,在很多編程語言中都有 base64模塊且功能基本相同。 所以在任何編程語言中,都可以將base64加密的字符串進行解密。
既然都可以進行解密,那么帶來的問題就是沒有安全可言了。其實不然,我們自然有辦法去解決。稍后我們通過一個小練習來解決這個問題。
base64 模塊 模塊中的常用方法
函數(shù)名 | 參數(shù) | 介紹 | 舉例 | 返回值 |
---|---|---|---|---|
encodestring | byte | 進行base64加密 | base64.encodestring(b’string’) | byte |
decodestring | byte | 進行base64解密 | base64.decodestring(b’c3RyaW5n\n’) | byte |
encodebytes | byte | 進行base64加密 | base64.encodebytes(b’string’) | byte |
decodebytes | byte | ?進行base64解密 | base64.decodebytes(b’c3RyaW5n\n’) | byte |
注意:encodestring()函數(shù) 與 decodestring() 函數(shù) 雖然從名字上來看是對 字符串 進行 加密解密,但是在用法上需要對字符串進行 byte 類型的轉(zhuǎn)換,然后再執(zhí)行對應的加密解密操作。
encodebytes()函數(shù) 與 decodebytes() 函數(shù) 功能、參數(shù)、返回值 與字符串加解密一致,實際上在 python3.x 中,官方更推薦使用著一組函數(shù)進行加密和解密。
base64 模塊的情景練習
接下來我們看一下 base64 模塊的 加解密演示那里:
注意:由于無論如何我們都需要通過 byte 類型進行數(shù)據(jù)的加密與解密,所以我們可以對加密、解密進行一個封裝。
# coding:utf-8 import base64 def encode(data): # 編碼函數(shù) if isinstance(data, str): # 判斷傳入的 data 的數(shù)據(jù)類型 data = data.encode('utf-8') elif isinstance(data, bytes): data = data else: raise TypeError('傳輸?shù)?\'data\' 參數(shù)需為 bytes 或 str 類型') # print(base64.encodebytes(data)) # print(base64.encodebytes(data).decode('utf-8')) return base64.encodebytes(data).decode('utf-8') # 加密后的 data 格式為byte類型,需要進行解碼為字符串,參考上兩行代碼 def decone(data): if not isinstance(data, bytes): raise TypeError('傳輸?shù)?\'data\' 參數(shù)需為 bytes 類型') 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 的加密方式與解密方式,那我們該如何是好呢?其實也很簡單,那就是對我們的 base64 加密的密文進行字符串替換的二次輸出。(所謂的二次輸出,其實就是二次轉(zhuǎn)換的過程。)
比如我們定義三個字符串專門用作加密后的某個字符的替換,代碼示例如下:
# coding:utf-8 import base64 replace_one = '$' replace_two = '%' replace_three = '=' def encode(data): # 編碼函數(shù) if isinstance(data, str): # 判斷傳入的 data 的數(shù)據(jù)類型 data = data.encode('utf-8') elif isinstance(data, bytes): data = data else: raise TypeError('傳輸?shù)?\'data\' 參數(shù)需為 bytes 或 str 類型') # print(base64.encodebytes(data)) # print(base64.encodebytes(data).decode('utf-8')) _data = base64.encodebytes(data).decode('utf-8') # 加密后的 data 格式為byte類型,需要進行解碼為字符串,參考上兩行代碼 _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 類型') 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é)果如下:
既然加密進行了二次轉(zhuǎn)換,那么解密的時候同樣需要進行二次轉(zhuǎn)換才行,所以我們需要重構(gòu)一下 decone() 函數(shù)。
def decone(data): if not isinstance(data, bytes): raise TypeError('傳輸?shù)?\'data\' 參數(shù)需為 bytes 類型') replace_one_decone = replace_one.encode('utf-8') # 需要將二次轉(zhuǎn)換的變量已 byte 的形式進行解碼 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')
運行結(jié)果如下:
小節(jié):通過這種方法,只有具體的開發(fā)人員與使用的業(yè)務人員才知道這種二次替換的方式,需要通過那些字符進行加密或者解密。從而提高了數(shù)據(jù)傳輸?shù)陌踩浴?/p>
原文鏈接:https://blog.csdn.net/weixin_42250835/article/details/123766881
相關(guān)推薦
- 2022-04-06 遠程過程調(diào)用RPC基本概念及實現(xiàn)原理_其它綜合
- 2022-12-03 Python學習之列表和元組的使用詳解_python
- 2024-02-28 UNI-APP中,swiper和tabbar結(jié)合實現(xiàn)滑動翻頁效果
- 2022-07-10 ENOENT讀取文件報錯(fs)
- 2022-06-22 git用戶自定義變量查看修改及調(diào)用教程詳解_其它綜合
- 2023-01-20 Django如何實現(xiàn)RBAC權(quán)限管理_python
- 2022-03-15 更新Android Studio 4.0 啟動模擬器提示 unable to locate adb
- 2022-08-04 react項目優(yōu)化配置的操作詳解_React
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學習環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支