欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python使用bcrypt?或?Passlib?對系統(tǒng)用戶密碼進行哈希和驗證處理操作

 更新時間:2024年08月22日 09:15:21   作者:伍華聰  
在Python?開發(fā)中,我們可以引入bcrypt?或?Passlib?對系統(tǒng)用戶密碼進行哈希和驗證處理,以及介紹使用其他類庫實現(xiàn)常規(guī)加解密處理操作,需要的朋友可以參考下

在設計一個系統(tǒng)的時候,肯定都有會有用戶身份認證的問題,一般對用戶校驗的時候,都是對用戶存在數(shù)據(jù)庫總的密碼哈希值進行判斷,從而避免密碼泄露和反向解密,那么在Python 開發(fā)中,我們可以引入bcrypt 或 Passlib 對系統(tǒng)用戶密碼進行哈希和驗證處理,以及介紹使用其他類庫實現(xiàn)常規(guī)加解密處理操作。本篇隨筆主要介紹bcrypt 和 Passlib 它們之間的差異,以及在實際使用中的一些代碼供參考。

1、bcrypt 和 Passlib的介紹

bcrypt 和 Passlib 都是用于密碼哈希和驗證的 Python 庫,但它們有一些顯著的區(qū)別:

  • bcrypt:

    • bcrypt 是一個專門用于實現(xiàn) bcrypt 哈希算法的庫。它相對簡單,專注于單一功能,即對密碼進行 bcrypt 哈希處理和驗證。
    • 適合只需要 bcrypt 哈希算法的場景。
    • 提供的 API 簡單直接,功能較少。
  • Passlib:

    • Passlib 是一個更高級的密碼哈希庫,它支持多種哈希算法(如 bcrypt、PBKDF2Argon2 等),并且提供了更豐富的功能。
    • 適合需要支持多種密碼哈希算法和策略的場景。
    • 提供的 CryptContext 類可以方便地管理和遷移多個哈希算法。還提供了密碼哈希的自動升級機制,以及對舊算法的棄用處理。

當你確定只需要使用 bcrypt 算法,并且不需要額外的復雜功能時,bcrypt 是一個合適的選擇。它適合簡單的項目,或者在需要直接控制 salt 等參數(shù)的情況下使用。

Passlib 適合復雜的項目,尤其是需要支持多個哈希算法或需要遷移哈希算法的場景。適合需要長期維護的項目,因為它提供了更多的配置和安全功能。

bcrypt: 靈活性較低,因為它只支持 bcrypt 算法。沒有多種哈希算法選擇或密碼策略管理功能。使用簡單,代碼更直觀。如果你只需要 bcrypt 算法,bcrypt 庫可能更容易上手。

Passlib:提供了很高的靈活性和擴展性??梢愿鶕?jù)需要切換和配置不同的哈希算法,管理復雜的密碼策略。通過 CryptContext,可以輕松管理不同算法之間的過渡。功能強大但相對復雜,需要更深入的學習和理解。但它的高層 API 設計得很友好,一旦熟悉,可以簡化很多常見任務。CryptContext 是其中一個用于管理多個哈希算法和密碼哈希策略的類。

示例代碼對比:

bcrypt 使用示例:

import bcrypt
password = b"supersecretpassword"
hashed = bcrypt.hashpw(password, bcrypt.gensalt())
# 驗證密碼
if bcrypt.checkpw(password, hashed):
    print("Password matches!")
else:
    print("Password does not match.")

Passlib 使用示例:

from passlib.context import CryptContext
# 創(chuàng)建一個 CryptContext 對象
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
# 哈希密碼
password = "my_secret_password"
hashed_password = pwd_context.hash(password)
print("Hashed password:", hashed_password)
# 驗證密碼
is_correct = pwd_context.verify(password, hashed_password)
if is_correct:
    print("密碼正確")
else:
    print("密碼錯誤")

定義了一個 CryptContext 對象,用于管理密碼哈希算法。schemes=["bcrypt"] 表示你要使用 bcrypt 算法,而 deprecated="auto" 表示自動管理過時的哈希方案。

使用 pwd_context.hash() 方法對密碼進行哈希處理。每次生成的哈希值都是唯一的,即使是相同的密碼也會生成不同的哈希值。

使用 pwd_context.verify() 方法可以驗證給定的密碼與存儲的哈希值是否匹配。

你還可以在創(chuàng)建 CryptContext 對象時傳遞更多參數(shù)來定制密碼哈希行為,這種方法可以增強密碼存儲的安全性。例如:

pwd_context = CryptContext(
    schemes=["bcrypt"],
    bcrypt__rounds=12  # bcrypt 的哈希輪數(shù),默認為 12
)

2、使用指定的salt進行加密

在 Passlib 中,bcrypt 算法默認會自動生成一個隨機的 salt,這也是 bcrypt 的一種安全特性。如果你想使用指定的 salt 進行加密,需要注意的是,Passlib 并不直接支持通過指定 salt 來進行哈希處理,因為這可能會降低安全性。

不過,如果你確實需要使用指定的 salt 進行哈希處理,你可以使用以下的方式:

  • 手動拼接 salt 和密碼:可以手動拼接 salt 和密碼,然后對結(jié)果進行哈希處理。但這種方法僅適用于了解風險并確保安全措施的場景。

  • 使用 bcrypt 庫:直接使用 bcrypt 庫進行處理,它允許你傳遞一個指定的 salt。不過,注意這會有一定的安全風險。

1) 使用bcrypt 庫指定 salt

如果你確實需要指定 salt,可以使用 bcrypt 庫。

import bcrypt
# 指定的 salt(必須為 16 字節(jié),前綴為 b"$2b$")
salt = bcrypt.gensalt(rounds=12)  # 或者使用自定義的 16 字節(jié) salt
print(f"Generated salt: {salt}")
# 要加密的密碼
password = "my_secret_password"
# 使用指定的 salt 進行加密
hashed_password = bcrypt.hashpw(password.encode('utf-8'), salt)
print(f"Hashed password: {hashed_password}")

2) 手動拼接 salt 和密碼

如果你使用 Passlib,并想使用指定的 salt,可以手動拼接 salt 和密碼,然后對這個組合結(jié)果進行哈希處理。這個方式一般不建議使用,因為它破壞了 bcrypt 的安全設計原則。

from passlib.context import CryptContext
# 創(chuàng)建一個 CryptContext 對象
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
# 自定義 salt
custom_salt = "my_custom_salt"
# 拼接 salt 和密碼
password = "my_secret_password"
password_with_salt = custom_salt + password
# 對拼接后的字符串進行哈希處理
hashed_password = pwd_context.hash(password_with_salt)
print("Hashed password with custom salt:", hashed_password)

注意事項

  • 使用固定的 salt 會降低密碼哈希的安全性,因為相同的 salt 和相同的密碼會生成相同的哈希值。
  • bcrypt 的設計初衷是讓每次生成的 salt 都不同,以此提高安全性。
  • 如果你需要在特定的場景下使用固定的 salt,一定要確保你的系統(tǒng)有足夠的其他安全措施。

同一密碼,每次獲得的hash值都會不同,那么有些人會問,如果通過pwd_context.hash獲得的hash值,下一次能夠?qū)Ρ日_嗎?

       回答是的,使用 pwd_context.hash() 生成的哈希值可以在后續(xù)對比中正確匹配,即使每次生成的哈希值看起來不同。Passlib 和 bcrypt 的設計確保了這一點。

  • 自動生成的 salt:每次你使用 pwd_context.hash() 生成一個新的哈希值時,bcrypt 都會自動生成一個隨機的 salt 并將其嵌入到生成的哈希值中。因此,即使對同一個密碼進行多次哈希,每次生成的哈希值也會不同。

  • 驗證過程:在驗證過程中,pwd_context.verify() 會自動從存儲的哈希值中提取 salt 并重新計算哈希,然后將其與提供的哈希值進行比較。這意味著,即使哈希值不同,驗證仍然能夠成功匹配。

即使你每次運行 pwd_context.hash(password) 得到的哈希值不同(因為 salt 不同),pwd_context.verify(password, hashed_password) 仍然會返回 True,表示密碼驗證成功。

3、加密和解密處理

Passlib 主要用于密碼哈希處理,并不支持加密和解密操作。如果你需要對字符串進行加密和解密,或者使用非對稱加密,你需要使用其他庫,例如 cryptography 或 PyCryptodome。

1)對稱加密和解密

對于對稱加密,你可以使用 cryptography 庫中的 Fernet,它是基于 AES 算法的加密方案。

安裝 cryptography 庫

pip install cryptography

對稱加密和解密示例

from cryptography.fernet import Fernet
# 生成密鑰(注意:密鑰需要安全存儲)
key = Fernet.generate_key()
cipher = Fernet(key)
# 加密
message = "This is a secret message"
encrypted_message = cipher.encrypt(message.encode())
print("Encrypted:", encrypted_message)
# 解密
decrypted_message = cipher.decrypt(encrypted_message).decode()
print("Decrypted:", decrypted_message)

2) 非對稱加密和解密

對于非對稱加密,你可以使用 cryptography 庫中的 RSA 算法。通常,非對稱加密用于加密較短的信息或加密對稱密鑰。

非對稱加密和解密示例

from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import serialization, hashes
# 生成私鑰和公鑰
private_key = rsa.generate_private_key(
    public_exponent=65537,
    key_size=2048,
)
public_key = private_key.public_key()
# 加密
message = b"This is a secret message"
encrypted_message = public_key.encrypt(
    message,
    padding.OAEP(
        mgf=padding.MGF1(algorithm=hashes.SHA256()),
        algorithm=hashes.SHA256(),
        label=None
    )
)
print("Encrypted:", encrypted_message)
# 解密
decrypted_message = private_key.decrypt(
    encrypted_message,
    padding.OAEP(
        mgf=padding.MGF1(algorithm=hashes.SHA256()),
        algorithm=hashes.SHA256(),
        label=None
    )
)
print("Decrypted:", decrypted_message.decode())

3)保存和加載密鑰

保存私鑰:

private_pem = private_key.private_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PrivateFormat.TraditionalOpenSSL,
    encryption_algorithm=serialization.NoEncryption()
)
with open('private_key.pem', 'wb') as f:
    f.write(private_pem)

加載私鑰:

with open('private_key.pem', 'rb') as f:
    private_key = serialization.load_pem_private_key(
        f.read(),
        password=None,
    )

保存公鑰:

public_pem = public_key.public_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PublicFormat.SubjectPublicKeyInfo
)
with open('public_key.pem', 'wb') as f:
    f.write(public_pem)

加載公鑰:

with open('public_key.pem', 'rb') as f:
    public_key = serialization.load_pem_public_key(f.read())

我們在開發(fā)過程總,可以根據(jù)需求選擇合適的加密方式和庫,并妥善管理密鑰。

到此這篇關(guān)于Python使用bcrypt 或 Passlib 對系統(tǒng)用戶密碼進行哈希和驗證處理 的文章就介紹到這了,更多相關(guān)Python用戶密碼哈希和驗證內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • pymysql.err.DataError:1366的報錯解決

    pymysql.err.DataError:1366的報錯解決

    通過python把數(shù)據(jù)同步至mysql數(shù)據(jù)庫的過程中,遇到錯誤,本文主要介紹了pymysql.err.DataError:1366的報錯解決,具有一定的參考價值,感興趣的可以了解一下
    2024-05-05
  • Keras - GPU ID 和顯存占用設定步驟

    Keras - GPU ID 和顯存占用設定步驟

    這篇文章主要介紹了Keras - GPU ID 和顯存占用設定步驟,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-06-06
  • Python 操作mysql數(shù)據(jù)庫查詢之fetchone(), fetchmany(), fetchall()用法示例

    Python 操作mysql數(shù)據(jù)庫查詢之fetchone(), fetchmany(), fetchall()用法示例

    這篇文章主要介紹了Python 操作mysql數(shù)據(jù)庫查詢之fetchone(), fetchmany(), fetchall()用法,結(jié)合實例形式分析了Python使用pymysql模塊的fetchone(), fetchmany(), fetchall()方法進行mysql數(shù)據(jù)庫查詢的操作技巧,需要的朋友可以參考下
    2019-10-10
  • 在Pycharm中項目解釋器與環(huán)境變量的設置方法

    在Pycharm中項目解釋器與環(huán)境變量的設置方法

    今天小編就為大家分享一篇在Pycharm中項目解釋器與環(huán)境變量的設置方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-10-10
  • python2使用bs4爬取騰訊社招過程解析

    python2使用bs4爬取騰訊社招過程解析

    這篇文章主要介紹了python2使用bs4爬取騰訊社招過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-08-08
  • python 基于pygame實現(xiàn)俄羅斯方塊

    python 基于pygame實現(xiàn)俄羅斯方塊

    這篇文章主要介紹了python 基于pygame實現(xiàn)俄羅斯方塊的方法,幫助大家更好的理解和學習使用python,感興趣的朋友可以了解下
    2021-03-03
  • python tornado上傳文件功能實現(xiàn)(前端和后端)

    python tornado上傳文件功能實現(xiàn)(前端和后端)

    Tornado 是一個功能強大的 Web 框架,除了基本的請求處理能力之外,還提供了一些高級功能,在 Tornado web 框架中,上傳圖片通常涉及創(chuàng)建一個表單,讓用戶選擇文件并上傳,本文介紹tornado上傳文件功能,感興趣的朋友一起看看吧
    2024-03-03
  • Python中DrissionPage的示例代碼

    Python中DrissionPage的示例代碼

    DrissionPage是一款集成了Selenium和Requests功能的Python庫,本文就來介紹一下DrissionPage的具體使用,文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學習學習吧
    2024-12-12
  • Python中類變量和實例變量的區(qū)別

    Python中類變量和實例變量的區(qū)別

    這篇文章主要介紹了Python中類變量和實例變量的區(qū)別,文章針對Python類變量和實例變量的問題,給出了具體說明和演示,需要的小伙伴可以參考一下
    2022-02-02
  • Python性能優(yōu)化的20條建議

    Python性能優(yōu)化的20條建議

    不論什么語言我們都需要注意性能優(yōu)化問題,提高執(zhí)行效率,這里就為大家分享下Python的性能優(yōu)化技巧,需要的朋友可以參考下
    2014-10-10

最新評論