Python单向加密实现密码校验的方案选择及落地实现方法咨询
问题1:方案合理性说明
你的核心思路**「仅存储密码哈希值、校验时比对输入的哈希结果」是密码存储校验的行业标准方案**,属于最优解范畴,但是有两个必须注意的优化点:
- 不能使用普通单向哈希函数(比如MD5、SHA-1、裸SHA256),这类函数运算速度极快,攻击者可通过彩虹表、暴力碰撞快速破解密文
- 必须使用专门为密码场景设计的慢哈希算法,这类算法默认自带随机盐、支持调整计算复杂度,抗爆破能力极强,常见可选的有Argon2、bcrypt、PBKDF2等
补充说明你遇到的
hash()函数问题:Python内置的hash()是为字典、集合这类哈希表结构设计的非加密哈希,默认开启了进程级随机盐,每次启动程序生成的哈希值都会变化,完全不适合密码加密场景,不要使用。
问题2:代码实现方案
方案1:使用Python标准库实现(无需安装第三方依赖,用PBKDF2算法)
import hashlib import os # 预设密码时生成哈希存储,存储内容是 盐+迭代次数+哈希值 拼接后的结果,不需要单独存盐 def generate_password_hash(password: str, iterations: int = 100000) -> bytes: # 生成16位随机盐 salt = os.urandom(16) # 用PBKDF2算法生成哈希 pwd_hash = hashlib.pbkdf2_hmac( hash_name='sha256', password=password.encode('utf-8'), salt=salt, iterations=iterations ) # 拼接所有参数存储,后续校验直接从存储值里拆分即可 return salt + iterations.to_bytes(4, byteorder='big') + pwd_hash # 校验用户输入的密码是否正确 def verify_password(input_pwd: str, stored_hash: bytes) -> bool: # 拆分存储的内容得到盐、迭代次数、原哈希值 salt = stored_hash[:16] iterations = int.from_bytes(stored_hash[16:20], byteorder='big') original_hash = stored_hash[20:] # 用相同参数计算输入密码的哈希 input_hash = hashlib.pbkdf2_hmac( hash_name='sha256', password=input_pwd.encode('utf-8'), salt=salt, iterations=iterations ) # 专用哈希比对函数,抗时序攻击 return hashlib.compare_digest(input_hash, original_hash) # 用法示例 if __name__ == '__main__': # 预设密码时生成哈希,存储这个哈希值即可,不要存明文 stored_pwd_hash = generate_password_hash("你的预设密码123") # 校验用户输入 user_input = input("请输入密码:") if verify_password(user_input, stored_pwd_hash): print("密码校验通过") else: print("密码错误")
方案2:使用第三方bcrypt库实现(代码更简洁,安全性更高)
首先安装依赖:pip install bcrypt
import bcrypt # 生成密码哈希,自动内置随机盐 def generate_password_hash(password: str) -> bytes: return bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()) # 校验密码 def verify_password(input_pwd: str, stored_hash: bytes) -> bool: return bcrypt.checkpw(input_pwd.encode('utf-8'), stored_hash) # 用法示例 if __name__ == '__main__': stored_hash = generate_password_hash("预设密码456") user_input = input("请输入密码:") if verify_password(user_input, stored_hash): print("校验通过") else: print("密码错误")
内容的提问来源于stack exchange,提问作者Nathan Dai
相关产品推荐
相关产品推荐

