max*_*yfc 44 python security passwords
如何将用户输入的密码存储在内存中,并在不再需要后将其安全擦除?
详细说明,目前我们有以下代码:
username = raw_input('User name: ')
password = getpass.getpass()
mail = imaplib.IMAP4(MAIL_HOST)
mail.login(username, password)
在调用该login方法之后,我们需要做些什么来填充包含带有乱码的密码的内存区域,以便有人无法通过执行核心转储来恢复密码?
有一个类似的问题,但它是在Java中,解决方案使用字符数组: 在创建帐户时,如何在内存中安全地存储密码?
这可以用Python完成吗?
Mil*_*les 41
Python对内存的控制水平不高.接受它,继续前进.您可以做的最好的事情是del password在调用之后mail.login,不保留对密码字符串对象的引用.任何声称能够做到这一点的解决方案只会给你一种虚假的安全感.
Python字符串对象是不可变的; 在创建字符串后,没有直接的方法来更改字符串的内容.即使你能够以某种方式覆盖所引用的字符串的内容password(这在技术上可能使用愚蠢的ctypes技巧),仍然会有各种字符串操作中创建的密码的其他副本:
你会以某种方式获得对所有这些字符串的引用并覆盖它们的内存.
amc*_*gor 19
实际上有一种方法可以安全地擦除Python中的字符串; 使用memset C函数,根据Mark数据在python中敏感
在帖子发布很久之后编辑添加:这里是对字符串实习的深入研究.在某些情况下(主要涉及非常量字符串),其中不会发生实习,基于CPython引用计数GC,使字符串值的清理稍微更明确.(虽然仍然不是"擦洗"/"消毒"清理.)
正确的解决方案是使用 bytearray() ...它是可变的,您可以安全地从 RAM 中清除密钥和敏感材料。
然而,有一些库,特别是 python“加密”库,阻止使用“bytearray”。这是有问题的......在某种程度上,这些密码库应该确保只有可变类型用于密钥材料。
有SecureString,它是一个 pip 模块,允许您从内存中完全删除密钥...(我对其进行了一些重构,并将其称为SecureBytes)。我编写了一些单元测试来证明密钥已完全删除。
但有一个很大的警告:如果某人的密码是“type”,那么“type”一词将从所有Python中删除......包括在函数定义和对象属性中。
换句话说......改变不可变类型是一个糟糕的主意,除非你非常小心,否则可能会立即使任何正在运行的程序崩溃。
正确的解决方案是:永远不要对密钥材料、密码等使用不可变类型。任何构建加密库或例程(如“getpass”)的人都应该使用“bytearray”而不是 python 字符串。