日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網(wǎng)站首頁 編程語言 正文

Python學習之加密模塊使用詳解_python

作者:渴望力量的哈士奇 ? 更新時間: 2022-05-31 編程語言

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

欄目分類
最近更新