在python中保护凭证存储

时间:2013-01-31 22:26:58

标签: python security reflection storage credentials

攻击

在凭证存储环境中,一种可能的威胁模型是攻击者,它具有以下能力:

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

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

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

Python

第一种技术很容易实现,可能是through a keyring(希望是内核空间存储)

在我不知情的情况下,如果没有编写C模块,第二个根本无法实现(但我希望在这里被证明是错误的,或者有一个现有模块列表)

第三个是棘手的。

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

似乎已达成共识there's no way to enforce private attributesattempts at it will at best annoy other programmers who are using your code

问题

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

2 个答案:

答案 0 :(得分:28)

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

  1. 验证您的用户:例如,您只允许用户在用户对您的程序进行身份验证后访问服务
  2. 使用其他程序或服务验证程序:例如,用户启动您的程序,然后使用IMAP通过Internet访问用户的电子邮件。
  3. 在第一种情况下,您不应该存储密码(或密码的加密版本)。相反,您应该使用高质量的盐哈希密码,并确保您使用的哈希算法在计算上非常昂贵(以防止字典攻击),例如PBKDF2或bcrypt。有关详细信息,请参阅Salted Password Hashing - Doing it Right。如果你采用这种方法,即使黑客检索到盐渍的,慢速哈希的令牌,他们也无法做到这一点。

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

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

    这种方法肯定比没有好,但是熟练的黑客迟早会破坏它。

    令牌

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

    • Out-of-band身份验证。例如,在我居住的地方,当我尝试登录我的网上银行时,我会在手机上收到one-time password(OTP)作为短信。在这种方法中,我证明了我拥有一个特定的电话号码
    • Security token:要登录服务,我必须按下令牌上的按钮才能获得OTP,然后将其用作我的密码。
    • 其他设备:

      • SmartCard,特别是美国国防部使用的CAC。 Python有一个名为pyscard的模块,用于与此
      • 接口
      • NFC设备

    更完整的列表here

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

    会话窃取

    但是(总有一个):

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

    这是一个非常真实的威胁,因为多个跨站点脚本攻击都有显示(一个例子是U.S. Bank and Bank of America Websites Vulnerable,但还有无数更多)。

    安全代理

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

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

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

    这种方法的缺点是:

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

    一些答案​​

    所以,具体答案:

      

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

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

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

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

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

    由于没有绝对的隐私,其余的只是混淆,保护程度就是混淆的难度和技术黑客想要的信息量。我们都知道that ends的方式,即使是custom hardwarebillion-dollar products

      

    使用Python密钥环

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

答案 1 :(得分:1)

我不是这个领域的专家,我真的只是想解决你遇到的同样问题,但看起来像Hashicorp's Vault这样的东西可能会很好地帮助你。

特别是WRT存储第三方服务的凭证问题。例如:

  

在API驱动的所有东西的现代世界中,许多系统还支持以编程方式创建访问凭证。 Vault通过称为动态机密的功能利用这种支持:按需生成的机密,并支持自动撤销。

     

对于Vault 0.1,Vault支持动态生成AWS,SQL和Consul凭据。

更多链接: