在python中保护凭证存储

gon*_*opp 14 python security reflection storage credentials

攻击

在凭证存储的上下文中,一种可能的威胁模型是攻击者,其能够:

  • 检查任何(用户)进程内存
  • 读取本地(用户)文件

AFAIK,对这种类型的攻击的共识是,它是不可能阻止的(因为凭证必须存储在内存中以便程序实际使用它们),但有几种技术可以缓解它:

  • 最小化敏感数据存储在内存中的时间
  • 一旦不再需要数据,就会覆盖内存
  • 通过默默无闻的措施来破坏内存中的数据,保持移动以及其他安全性

特别是Python

第一种技术很容易实现,可能通过密钥环 (希望内核空间存储)

根据我的知识,第二个是没有编写C模块就完全无法实现(但我希望在这里被证明是错误的,或者有一个现有模块列表)

第三个是棘手的.

特别是,python是一种具有非常强大的内省和反射功能的语言,很难阻止对可以在解释器进程中执行python代码的任何人访问凭据.

似乎已达成共识,即无法强制实施私有属性,并且尝试使用私有属性最多会惹恼使用您的代码的其他程序员.

这个问题

综合考虑所有这些因素,如何使用python安全地存储身份验证凭据?什么是最佳做法?关于语言"一切都是公共的"哲学可以做些什么吗?我知道"我们都在同意这里的成年人",但我们是否应该在与攻击者共享密码和使用其他语言之间做出选择?

And*_*ock 28

存储身份验证凭据的原因有两个非常不同的原因:

  1. 用户进行身份验证:例如,您只允许用户在用户对您的程序进行身份验证后访问服务
  2. 使用其他程序或服务对程序进行身份验证:例如,用户启动程序,然后使用IMAP通过Internet访问用户的电子邮件.

在第一种情况下,您不应该存储密码(或密码的加密版本).相反,您应该使用高质量的盐散列密码,并确保您使用的散列算法在计算上非常昂贵(以防止字典攻击),例如PBKDF2或bcrypt.请参阅Salted Password Hashing - 正确执行以获取更多详细信息.如果您遵循这种方法,即使黑客检索到盐渍的慢速哈希令牌,他们也无法做很多事情.

在第二种情况下,有许多事情可以使秘密发现变得更难(如您在问题中所述),例如:

  • 保持秘密加密直到需要,按需解密,然后立即重新加密
  • 使用地址空间随机化,因此每次应用程序运行时,密钥都存储在不同的地址
  • 使用OS密钥库
  • 使用"硬"语言(如C/C++)而不是基于VM的内省语言(如Java或Python)

这样的方法当然比没有好,但是熟练的黑客迟早会破坏它.

令牌

从理论的角度来看,认证是证明受到挑战的人是他们所说的人的行为.传统上,这是通过共享密钥(密码)实现的,但还有其他方法可以证明自己,包括:

  • 带外认证.例如,在我居住的地方,当我尝试登录我的网上银行时,我会在手机上收到一次性密码(OTP)作为短信.在这种方法中,我证明了我拥有一个特定的电话号码
  • 安全令牌:要登录服务,我必须按下令牌上的按钮才能获得OTP,然后将其用作我的密码.
  • 其他设备:

而一个更完整的列表在这里

所有这些方法之间的共同点是最终用户控制这些设备并且秘密永远不会真正离开令牌/卡/电话,并且当然永远不会存储在您的程序中.这使他们更安全.

会话窃取

然而(总有一个):

让我们假设您设法保护登录,以便黑客无法访问安全令牌.现在,您的应用程序很乐意与安全服务进行交互.不幸的是,如果黑客可以在您的计算机上运行任意可执行文件,黑客可以劫持您的会话,例如通过向您有效使用该服务注入其他命令.换句话说,虽然您已经保​​护了密码,但它完全无关紧要,因为黑客仍然可以访问"安全"资源.

这是一个非常真实的威胁,因为多个跨站点脚本攻击已经显示(一个例子是美国银行和美国银行网站易受攻击,但还有无数更多).

安全代理

如上所述,将帐户的凭证保留在第三方服务或系统上存在一个基本问题,以便应用程序可以登录它,特别是如果唯一的登录方法是用户名和密码.

通过将通信委托给安全代理服务来部分缓解这种情况的一种方法,并在应用程序和代理之间开发安全的登录方法.在这种方法

  • 该应用程序使用PKI方案或双因素身份验证来登录安全代理
  • 用户将安全凭证添加到第三方系统到安全代理.凭据永远不会存储在应用程序中
  • 稍后,当应用程序需要访问第三方系统时,它会向代理发送请求.代理使用安全凭证登录并发出请求,并将结果返回给应用程序.

这种方法的缺点是:

  • 用户可能不希望使用凭证的存储来信任安全代理
  • 用户可能不信任安全代理,其中数据流经第三方应用程序
  • 应用程序所有者具有运行代理的额外基础结构和托管成本

一些答案

所以,具体答案:

如何使用python安全地存储身份验证凭据?

  • 如果为应用程序存储密码以验证用户,请使用PBKDF2算法,例如https://www.dlitz.net/software/python-pbkdf2/
  • 如果存储密码/安全令牌来访问另一个服务,那么就没有绝对安全的方法.
  • 然而,考虑使用例如pyscard将认证策略切换到例如智能卡.您可以使用智能卡对应用程序的用户进行身份验证,还可以使用X.509证书将应用程序安全地验证到其他服务.

关于语言"一切都是公共的"哲学可以做些什么吗?我知道"我们都在同意这里的成年人",但我们是否应该在与攻击者共享密码和使用其他语言之间做出选择?

恕我直言,在Python中编写一个特定的模块没有任何问题,它隐藏了秘密信息,使其成为其他人重用的正确错误(令其他程序员烦恼是其目的).您甚至可以在C中编写大部分代码并链接到它.但是,出于显而易见的原因,不要为其他模块执行此操作.

但最终,如果黑客能够控制计算机,那么计算机上根本就没有隐私.理论上最糟糕的情况是您的程序在VM中运行,并且黑客可以完全访问计算机上的所有内存,包括BIOS和图形卡,并且可以通过身份验证来处理您的应用程序以发现其秘密.

由于没有绝对的隐私,其余的只是模糊处理,保护程度就是模糊处理的难度与熟练的黑客对信息的需求程度.我们都知道如何结束,即使是定制硬件和价值数十亿美元的产品.

使用Python密钥环

虽然这将非常安全地管理与其他应用程序相关的密钥,但所有Python应用程序都共享对令牌的访问权限.对于你担心的攻击类型来说,这并不是一点点安全.