安全删除内存中的密码(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[:] = '' 

您将不得不确定密码的最大大小,但是这应该在数据被覆盖时删除。

将密码存储在列表中,如果您只将列表设置为空,则列表中存储的数组内存将自动释放。

编辑:删除不好的build议…

如果你愿意的话,你也可以使用像java这样的数组,但是只要覆盖它就足够了。

http://docs.python.org/library/array.html