不能用input()读密码,因其明文显示且存入命令历史;应使用getpass.getpass()屏蔽输入,但需注意其在非tty环境可能失效、不校验长度、不处理ctrl+c,且密码入内存后仍需防范泄露。

为什么不能用input()读密码
直接用 input() 读密码,输入内容会明文显示在终端上,别人从旁边就能看到。更糟的是,命令历史里也会留下记录,比如 Bash 的 ~/.bash_history 会存下整行命令(含密码)。这不是“不安全”,是根本没设防。
getpass.getpass() 的基本用法和限制
getpass.getpass() 默认屏蔽输入字符(不回显),也不写入 shell 历史。但它只处理标准输入流,且不支持 Windows 下的某些终端模拟器(如 Git Bash 的 mintty)——这时会抛出 GetPassWarning 警告,但依然返回输入内容(只是没隐藏)。
- 默认提示符是
'Password: ',可传入字符串覆盖:getpass.getpass('Enter API key: ') - 它不校验输入长度、不自动 trim 空格,空格会被当成密码一部分
- 无法捕获 Ctrl+C 后的中断信号(会抛出
KeyboardInterrupt,需手动 try-except) - 在 Jupyter 或 IDE 的内置终端中可能失效,因为 stdin 不是真实 tty
常见错误:混用 sys.stdin.readline() 和 getpass
有人想“加个换行”或“去掉末尾\n”,于是写 sys.stdin.readline().strip() ——这完全绕过了 getpass 的屏蔽逻辑,密码立刻明文可见。正确做法只有两个:
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
- 坚持只用
getpass.getpass(),它内部已调用sys.stdin.readline()并自动 strip 了换行符 - 如果真要预处理(比如强制小写),必须在
getpass.getpass()返回后再操作:pwd = getpass.getpass().lower()
别碰 sys.stdin,那是自毁式操作。
生产环境该注意什么
密码进了 Python 进程内存后,就不再是“安全”的了:Python 的字符串不可变,旧对象可能残留在内存里;GC 不保证立即清理;core dump 或调试器也可能抓到。所以:
- 拿到密码后尽快使用(比如发 HTTP 请求),别长期持有
- 避免日志打印、repr、traceback 泄露变量名或值(哪怕只是局部变量)
- 不要用
os.environ临时存密码——环境变量可能被子进程继承或被ps aux看见 - 如果需要多次使用,考虑用
secrets模块生成临时 token 替代明文密码流转
getpass 解决的只是“键盘到内存”这一段的明文暴露,后面全靠你自己盯住。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










