安全删除内存中的密码(Python)
如何将用户input的密码存储在内存中,并在不再需要时将其安全地擦除?
详细来说,目前我们有以下代码:
username = raw_input('User name: ') password = getpass.getpass() mail = imaplib.IMAP4(MAIL_HOST) mail.login(username, password)
在调用login
方法之后,我们需要做些什么来填充包含带有乱码的密码的内存区域,以便有人无法通过执行核心转储来恢复密码?
有一个类似的问题,但是它是用Java编写的,解决scheme使用字符数组: 在创build帐户时,如何在内存中安全地存储密码?
这可以在Python中完成吗?
Python对内存的控制水平并不那么低。 接受它,然后继续。 最好的办法是在调用mail.login
之后调用del password
,以保持对密码string对象的引用。 任何声称能够做得比这更多的解决scheme只会给你一种虚假的安全感。
Pythonstring对象是不可变的; 没有直接的方法来改变一个string的内容创build后。 即使你能够以某种方式覆盖password
引用的string的内容(这在技术上是愚蠢的ctypes技巧可能的),仍然会有其他各种string操作中创build的密码的副本:
- 当它从input的密码中除去尾随的换行符时,由getpass模块执行
- 当它引用密码时由imaplib模块完成,然后在将其传递给套接字之前创build完整的IMAP命令
你将不知何故必须得到所有这些string的引用,并覆盖它们的内存。
实际上,这是一种在Python中安全擦除string的方法。 使用memset C函数,因为在python中将数据标记为敏感数据
如果你不需要邮件对象,一旦你完成了它,我认为你最好的select是在一个subprocess中执行邮件工作(参见subprocess模块)。这样,当subprocess死了,那么你的密码。
这可以使用numpy chararray完成:
import numpy as np username = raw_input('User name: ') mail = imaplib.IMAP4(MAIL_HOST) x = np.chararray((20,)) x[:] = list("{:<20}".format(raw_input('Password: '))) mail.login(username, x.tobytes().strip()) x[:] = ''
您将不得不确定密码的最大大小,但是这应该在数据被覆盖时删除。
将密码存储在列表中,如果您只将列表设置为空,则列表中存储的数组内存将自动释放。