直接用pickle或明文存密码极不安全,因无加密防护且base64仅为编码;须用pbkdf2hmac加盐迭代派生密钥,配合fernet对称加密,并严格管理salt存储、内存清零及文件版本校验。

为什么直接用 pickle 或明文存密码会出事
因为 Tkinter 本身不提供加密能力,很多人第一步就错:把 passwords = {"gmail": "123456"} 直接 pickle.dump() 到文件里。这等于把密码写在记事本里锁上抽屉——抽屉没锁死,钥匙还贴在门框上。base64 编码也不是加密,只是可逆的编码,用 base64.b64decode() 一秒还原。真正需要的是密钥派生 + 对称加密,且密钥不能硬编码、不能从密码明文直来。
用 fernet 加密前必须处理好密钥派生
Fernet 要求 32 字节 URL 安全 base64 编码密钥,但用户输的密码(比如 "myPass123")既短又弱。不能 hashlib.sha256(pwd.encode()).digest() 直接当密钥——这没加盐、没迭代,GPU 一跑几亿次就撞出来。正确做法是用 pbkdf2_hmac 派生:
from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC import os <p>password = b"myPass123" salt = b"fixed_salt_is_bad" # ⚠️ 实际必须每次生成随机 salt 并存进文件头! kdf = PBKDF2HMAC( algorithm=hashes.SHA256(), length=32, salt=salt, iterations=480000, # Python 3.9+ 推荐 ≥ 480000 ) key = base64.urlsafe_b64encode(kdf.derive(password))</p>
注意:salt 必须随机且和密文一起保存(比如前 16 字节),否则换设备/重装就打不开数据。
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
Tkinter 界面里怎么安全地收密码而不留痕
Entry 默认会把密码存在内存里,如果用户复制粘贴、或程序崩溃 dump 内存,可能泄露。必须做两件事:
- 用
show="•"隐藏输入,但别用show="*"(某些字体下 * 易被 OCR 识别) - 输入完立刻把
Entry.get()结果转成bytes,参与密钥派生后立即调用del password_str;更稳妥的是用array.array("B", ...)手动清零内存 - 避免把解密后的明文密码长期保留在
StringVar或全局 dict 中——查完就del decrypted_dict["gmail"]
数据文件结构要带版本和校验,不然一升级就全废
别把加密数据直接写进 data.bin。头部至少放 3 样东西:version: 1(uint8)、salt(16 bytes)、encrypted_data(剩余全部)。读取时先校验 version,再切出 salt,最后解密。否则哪天你把 iterations 从 480000 改成 600000,老文件就永远打不开。另外,Fernet 自带 HMAC 校验,但如果密文被截断或损坏,Fernet.decrypt() 会抛 cryptography.fernet.InvalidToken,必须捕获并提示“文件损坏或密码错误”,而不是让界面卡死。
加密不是加个 encrypt() 就完事,密钥生命周期管理、内存清理、文件格式演进,每一步漏掉都可能让“安全”变成幻觉。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










