哈希和加密
理解哈希和加密的区别与适用场景
掌握
hashlib模块的常用哈希算法了解对称加密与非对称加密的基础使用
核心讲解
(1)哈希与加密的区别
哈希(Hash):单向变换,明文→哈希值,不可逆,不能解密。用于完整性校验、密码存储、去重。
加密:双向变换,明文→密文,有密钥可以解密。用于数据传输、隐私保护。
(2)常用哈希算法
MD5:128 位,速度快,安全性低,用于文件校验、非敏感场景
SHA-1:160 位,已被破解,不推荐安全场景
SHA-256:256 位,安全性高,是当前主流安全哈希
SHA-512:512 位,安全性更高,速度稍慢
(3)hashlib 模块使用
创建哈希对象:
hashlib.md5()、hashlib.sha256()更新数据:
update(字节),可以多次调用获取结果:
hexdigest()十六进制字符串、digest()原始字节
(4)密码哈希加盐
直接哈希密码不安全,要加盐(随机字符串)再哈希,防止彩虹表破解。可以用 hashlib 手动实现,也可以用 bcrypt 等专业库。
(5)加密算法
对称加密:加密解密用同一个密钥,速度快,适合大数据。代表:AES
非对称加密:公钥加密,私钥解密,速度慢,适合小数据、密钥交换。代表:RSA
代码示例
import hashlib
import os
# ===== 1. 基础哈希 =====
text = "Hello Python"
# MD5
md5 = hashlib.md5(text.encode("utf-8")).hexdigest()
print("MD5:", md5)
# SHA256
sha256 = hashlib.sha256(text.encode("utf-8")).hexdigest()
print("SHA256:", sha256)
# ===== 2. 大文件哈希校验 =====
def file_md5(file_path):
"""计算大文件的MD5,分批读取,不占内存"""
md5 = hashlib.md5()
with open(file_path, "rb") as f:
while True:
chunk = f.read(8192) # 每次读8KB
if not chunk:
break
md5.update(chunk)
return md5.hexdigest()
# 示例
# print("文件MD5:", file_md5("test.txt"))
# ===== 3. 密码加盐哈希 =====
def hash_password(password):
"""加盐哈希密码"""
# 生成16字节随机盐
salt = os.urandom(16)
# 密码+盐一起哈希,迭代多次
pwd_hash = hashlib.pbkdf2_hmac(
"sha256",
password.encode("utf-8"),
salt,
100000 # 迭代次数,越大越慢越安全
)
# 盐+哈希一起存,验证时用同一个盐
return salt.hex() + pwd_hash.hex()
def verify_password(password, stored):
"""验证密码"""
salt = bytes.fromhex(stored[:32])
stored_hash = stored[32:]
pwd_hash = hashlib.pbkdf2_hmac(
"sha256",
password.encode("utf-8"),
salt,
100000
).hex()
return pwd_hash == stored_hash
# 测试
pwd = "123456"
stored = hash_password(pwd)
print("存储的密码哈希:", stored)
print("密码验证正确:", verify_password(pwd, stored))
print("密码验证错误:", verify_password("123457", stored))
# ===== 4. AES对称加密示例(需安装pycryptodome) =====
# from Crypto.Cipher import AES
# 加密:明文+密钥→密文
# 解密:密文+密钥→明文
常见误区
把哈希当加密:MD5、SHA 都是哈希,不是加密,不能解密,不要说 “MD5 加密”
直接哈希密码:不加盐的密码哈希可以用彩虹表破解,必须加盐
MD5 用于安全场景:MD5 已被破解,敏感场景不要用,至少用 SHA256
哈希碰撞认知:理论上所有哈希都有碰撞概率,安全场景用更长的哈希值
自己实现加密算法:不要自己造加密算法,用标准库和成熟方案
课后练习
计算一个本地文件的 MD5 和 SHA256 值
实现一个用户注册登录的密码校验功能,用加盐哈希
了解 AES 加密的使用,尝试加密一段文本再解密
思考:为什么下载网站经常提供文件的 MD5 值?
