Python 加密与解密实战 18 招一散列哈希加密系列文章导航第一篇散列哈希加密招式1-4第二篇对称加密招式5-9第三篇非对称加密·数字签名·密钥交换招式10-13第四篇文件加密·扩展算法·安全随机数招式14-18前言在信息安全领域加密与解密是核心技术。Python 生态提供了丰富的加密库本系列文章将通过18 个实战招式系统讲解 Python 加密解密的完整知识体系。实验环境项目信息服务器华为云 FlexusX ECS操作系统Ubuntu 24.04 server 64bitCPU/内存8vCPUs / 16GiBPython3.12.3核心依赖cryptography 41.0.7、bcrypt 3.2.2、pycryptodome 3.23.0加密解密知识体系总览Python 加密解密 18 招 ├── 散列哈希 (招式1-4) │ ├── hashlib模块 (MD5/SHA系列) │ ├── 加盐处理 (Salt) │ ├── bcrypt模块 │ └── hmac模块 ├── 对称加密 (招式5-9) │ ├── AES加密 │ ├── AES进阶 (Fernet) │ ├── AES分组模式 (ECB/CBC/CTR/GCM/CFB/OFB) │ ├── DES/3DES加密 │ └── Blowfish加密 ├── 非对称加密 (招式10-13) │ ├── RSA加密 │ ├── DSA签名 │ ├── 数字签名 (PSS/PKCS1v15) │ └── DH/ECDH密钥交换 ├── 文件与扩展 (招式14-18) │ ├── hashlib文件签名 │ ├── cryptography文件签名 │ ├── 文件加密 (Fernet/AES-CBC/AES-GCM) │ ├── 扩展算法 (ARC4/CAST5/ChaCha20/Camellia/SM4/ECC) │ └── 密码学安全随机数三大加密算法分类类型特点典型算法适用场景散列哈希单向不可逆、固定长度输出MD5、SHA系列、bcrypt密码存储、完整性校验对称加密加解密同一密钥、速度快AES、DES、Blowfish大量数据加密非对称加密公钥加密/私钥解密、速度慢RSA、DSA、ECC密钥交换、数字签名招式1hashlib 模块 —— MD5/SHA 系列散列加密1.1 散列函数基础散列Hash函数是将任意长度的输入映射为固定长度输出的单向函数。核心特性确定性相同输入永远产生相同输出雪崩效应输入微小变化导致输出剧烈变化不可逆性无法从哈希值反推原始数据抗碰撞性很难找到两个不同输入产生相同输出1.2 hashlib 支持的算法importhashlib# 查看所有可用算法print(fhashlib可用算法:)foralgoinsorted(hashlib.algorithms_available):print(f -{algo})运行输出hashlib可用算法: - blake2b - blake2s - md5 - md5-sha1 - ripemd160 - sha1 - sha224 - sha256 - sha384 - sha3_224 - sha3_256 - sha3_384 - sha3_512 - sha512 - sha512_224 - sha512_256 - shake_128 - shake_256 - sm31.3 常用散列算法实战importhashlib textHello, Python Crypto!print(f原始文本:{text})# MD5 - 128位(16字节)哈希值md5_hashhashlib.md5(text.encode()).hexdigest()print(f\nMD5 ({len(md5_hash)}位十六进制 {len(md5_hash)*4}位):)print(f{md5_hash})# SHA1 - 160位(20字节)哈希值sha1_hashhashlib.sha1(text.encode()).hexdigest()print(f\nSHA1 ({len(sha1_hash)}位十六进制 {len(sha1_hash)*4}位):)print(f{sha1_hash})# SHA256 - 256位(32字节)哈希值sha256_hashhashlib.sha256(text.encode()).hexdigest()print(f\nSHA256 ({len(sha256_hash)}位十六进制 {len(sha256_hash)*4}位):)print(f{sha256_hash})# SHA512 - 512位(64字节)哈希值sha512_hashhashlib.sha512(text.encode()).hexdigest()print(f\nSHA512 ({len(sha512_hash)}位十六进制 {len(sha512_hash)*4}位):)print(f{sha512_hash})# SHA3-256 - 新一代SHA3标准sha3_hashhashlib.sha3_256(text.encode()).hexdigest()print(f\nSHA3-256 ({len(sha3_hash)}位十六进制 {len(sha3_hash)*4}位):)print(f{sha3_hash})运行输出原始文本: Hello, Python Crypto! MD5 (32位十六进制 128位): 6f3be9312107c24b560d1b6c4ea9ffe2 SHA1 (40位十六进制 160位): 71dbfc90be603c20a2e908451965502e9b0185a3 SHA256 (64位十六进制 256位): 17baf00e4e7fae0955ed1666e02c22f03bbfa7487227a767d529954b2c64f8de SHA512 (128位十六进制 512位): f152f6c5bcabbc25cb4aa03095be2d921efb2dbab89b326c5b4319d43719bbd35779cc4eb2615a3f163025723c89f6d4e329e5ab34ed034d3e0a30d4845e5367 SHA3-256 (64位十六进制 256位): fc58e962e260ae7a18914d296f28f83cdf84550b2e2f888231ebdad05d3114461.4 大文件分块哈希处理大文件时应分块读取避免内存溢出importhashlib# 模拟10MB大文件数据large_databX*(10*1024*1024)# 10MB数据hhashlib.sha256()foriinrange(0,len(large_data),4096):h.update(large_data[i:i4096])print(f10MB数据SHA256:{h.hexdigest()})运行输出10MB数据SHA256: 5449ecf9b06ad82bf75a0f1de67f1d8b40142c416dc93039c84a3ae6a98bb2cb1.5 雪崩效应演示importhashlibprint(fabc MD5:{hashlib.md5(babc).hexdigest()})print(fabd MD5:{hashlib.md5(babd).hexdigest()})print((仅改变1个字符哈希值完全不同))运行输出abc MD5: 900150983cd24fb0d6963f7d28e17f72 abd MD5: 4911e516e5aa21d327512e0c8b197616 (仅改变1个字符哈希值完全不同)小结MD5 已被证明不安全存在碰撞攻击生产环境推荐使用 SHA-256 及以上。SHA-3 是新一代哈希标准提供了与 SHA-2 不同的内部结构。招式2加盐处理Salt2.1 为什么需要加盐无盐哈希的致命弱点相同密码始终产生相同哈希值攻击者可以使用彩虹表预计算攻击。加盐通过为每个密码添加随机值使相同密码产生不同哈希。2.2 加盐实战importhashlibimportosimporttime passwordmypassword123# 无盐哈希 - 容易被彩虹表破解plain_hashhashlib.sha256(password.encode()).hexdigest()print(f原始密码:{password})print(f无盐SHA256:{plain_hash})# 随机盐值saltos.urandom(16)print(f\n随机盐值(16字节):{salt.hex()})# 加盐哈希 - 方式1: salt passwordsalted_hash1hashlib.sha256(saltpassword.encode()).hexdigest()print(f加盐SHA256(saltpwd):{salted_hash1})# 加盐哈希 - 方式2: password saltsalted_hash2hashlib.sha256(password.encode()salt).hexdigest()print(f加盐SHA256(pwdsalt):{salted_hash2})运行输出原始密码: mypassword123 无盐SHA256: 6e659deaa85842cdabb5c6305fcc40033ba43772ec00d45c2a3c921741a5e377 随机盐值(16字节): 190d7cc9d3249da4a11dffeb487be6d2 加盐SHA256(saltpwd): 5494981c3d48c57899ed943ee9031fd3abf602dcb169573a6ffb6cc0b160034b 加盐SHA256(pwdsalt): 591a880269b123845e00c0eada7165926a5a62e207ec09a1b254eb0e29f321c32.3 PBKDF2 多轮迭代iterations100000starttime.time()dkhashlib.pbkdf2_hmac(sha256,password.encode(),salt,iterations)elapsedtime.time()-startprint(fPBKDF2-HMAC-SHA256 (迭代{iterations}次):)print(f 密钥:{dk.hex()})print(f 耗时:{elapsed:.3f}秒)运行输出PBKDF2-HMAC-SHA256 (迭代100000次): 密钥: 684eab10994f67df36739f44f95b86491f257899a154b4fed20f0612820c1b18 耗时: 0.024秒2.4 同密码不同盐对比salt2os.urandom(16)salted_hash3hashlib.sha256(salt2password.encode()).hexdigest()print(f同密码不同盐的哈希对比:)print(f 盐1哈希:{salted_hash1})print(f 盐2哈希:{salted_hash3})print(f 是否相同:{salted_hash1salted_hash3})运行输出同密码不同盐的哈希对比: 盐1哈希: 5494981c3d48c57899ed943ee9031fd3abf602dcb169573a6ffb6cc0b160034b 盐2哈希: 31562836a306aca540a09324a87925076a575a24ecdd8f3d99f324988aebd89b 是否相同: False小结加盐使彩虹表攻击失效。PBKDF2 通过多轮迭代增加计算成本有效抵御暴力破解。推荐迭代次数不低于 100,000 次。招式3bcrypt 模块 —— 专业密码哈希3.1 bcrypt 优势bcrypt 是专为密码存储设计的哈希函数相比 PBKDF2 具有以下优势自动加盐盐值嵌入在哈希结果中无需单独存储自适应成本通过rounds参数控制计算复杂度抗 GPU/ASIC 攻击内存访问模式使其难以并行加速3.2 bcrypt 实战importbcryptimporttime passwordmypassword123pwd_bytespassword.encode(utf-8)# 生成盐并哈希salt_bcryptbcrypt.gensalt(rounds12)print(fbcrypt生成的盐:{salt_bcrypt.decode()})hashedbcrypt.hashpw(pwd_bytes,salt_bcrypt)print(fbcrypt哈希结果:{hashed.decode()})# 验证密码is_validbcrypt.checkpw(pwd_bytes,hashed)print(f\n密码验证(正确密码):{通过ifis_validelse失败})is_valid_wrongbcrypt.checkpw(bwrongpassword,hashed)print(f密码验证(错误密码):{通过ifis_valid_wrongelse失败})运行输出bcrypt生成的盐: $2b$12$5LGzB.jIXVT1TVOQzmbARu bcrypt哈希结果: $2b$12$5LGzB.jIXVT1TVOQzmbARuFb.jRBnBwYyd0urjLMQE8yBPdaxQNHK 密码验证(正确密码): 通过 密码验证(错误密码): 失败3.3 计算轮数性能对比print(不同rounds(计算轮数)性能对比:)forroundsin[4,8,12,14]:starttime.time()salt_testbcrypt.gensalt(roundsrounds)bcrypt.hashpw(pwd_bytes,salt_test)elapsedtime.time()-startprint(f rounds{rounds:2d}耗时:{elapsed:.4f}秒)运行输出不同rounds(计算轮数)性能对比: rounds 4 耗时: 0.0009秒 rounds 8 耗时: 0.0129秒 rounds12 耗时: 0.2053秒 rounds14 耗时: 0.8214秒小结rounds每增加 1计算时间翻倍。推荐生产环境使用rounds12约 0.2 秒在安全性和用户体验之间取得平衡。bcrypt 哈希结果格式$2b$rounds$salthash中自带了盐和轮数信息验证时自动提取。招式4hmac 模块 —— 消息认证码4.1 HMAC 原理HMACHash-based Message Authentication Code是一种使用密钥的消息认证码。与普通哈希的区别特性普通哈希HMAC需要密钥否是防篡改是是防伪造否任何人可计算是需要密钥身份认证否是4.2 HMAC 实战importhmacimporthashlib secret_keybmy_secret_key_2024messagebImportant message to verify# HMAC-MD5hmac_md5hmac.new(secret_key,message,hashlib.md5).hexdigest()print(fHMAC-MD5:{hmac_md5})# HMAC-SHA256hmac_sha256hmac.new(secret_key,message,hashlib.sha256).hexdigest()print(fHMAC-SHA256:{hmac_sha256})# HMAC-SHA512hmac_sha512hmac.new(secret_key,message,hashlib.sha512).hexdigest()print(fHMAC-SHA512:{hmac_sha512})运行输出HMAC-MD5: e7cfa5bee68e1ceb90358a40e72bcd4c HMAC-SHA256: 1a674b34376f5c172a0c365b4bd0b5ce165f64e70db53751b775c5303d7e5b94 HMAC-SHA512: f0711edd74edb61a351778eb71a1f9c6f0c2b509a43aabd3154553b26dc754b0b0dce52ed73b9e3919787c7f13e16a153776d3f5e24ddedb5487b4d76dda10ad4.3 HMAC 验证与防时序攻击# HMAC验证 - 安全比较received_hmachmac.new(secret_key,message,hashlib.sha256).hexdigest()is_matchhmac.compare_digest(hmac_sha256,received_hmac)print(f\nHMAC验证(正确消息):{匹配ifis_matchelse不匹配})# 篡改消息后的HMACtampered_msgbImportant message to VERIFIEDtampered_hmachmac.new(secret_key,tampered_msg,hashlib.sha256).hexdigest()is_match_tamperedhmac.compare_digest(hmac_sha256,tampered_hmac)print(fHMAC验证(篡改消息):{匹配ifis_match_tamperedelse不匹配})# 使用不同密钥wrong_key_hmachmac.new(bwrong_key,message,hashlib.sha256).hexdigest()is_match_wronghmac.compare_digest(hmac_sha256,wrong_key_hmac)print(fHMAC验证(错误密钥):{匹配ifis_match_wrongelse不匹配})运行输出HMAC验证(正确消息): 匹配 HMAC验证(篡改消息): 不匹配 HMAC验证(错误密钥): 不匹配小结hmac.compare_digest()是常量时间比较函数防止时序攻击。永远不要用比较 HMAC 值因为会在第一个不匹配字节处短路返回攻击者可通过测量响应时间逐字节猜测正确值。本篇总结招式模块核心用途安全等级1hashlib数据指纹/完整性校验SHA-256 推荐2hashlib os密码加盐哈希PBKDF2 推荐3bcrypt密码存储专业最高自适应成本4hmac消息认证/防篡改SHA-256 推荐安全实践建议密码存储优先 bcrypt其次 PBKDF2迭代 ≥ 100,000完整性校验使用 SHA-256 及以上避免 MD5/SHA-1消息认证始终使用hmac.compare_digest()进行比较盐值管理每个密码使用独立随机盐盐值长度 ≥ 16 字节下一篇Python 加密与解密实战 18 招二对称加密 AES/DES/Blowfish